kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix various issues with release notes channel.
rodzic
90e6dd3d7d
commit
84296a3860
|
@ -1,9 +1,6 @@
|
|||
package org.thoughtcrime.securesms.blocked;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -15,6 +12,7 @@ import androidx.fragment.app.Fragment;
|
|||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.thoughtcrime.securesms.BlockUnblockDialog;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
|
@ -74,24 +72,9 @@ public class BlockedUsersFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void handleRecipientClicked(@NonNull Recipient recipient) {
|
||||
AlertDialog confirmationDialog = new AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.BlockedUsersActivity__unblock_user)
|
||||
.setMessage(getString(R.string.BlockedUsersActivity__do_you_want_to_unblock_s, recipient.getDisplayName(requireContext())))
|
||||
.setPositiveButton(R.string.BlockedUsersActivity__unblock, (dialog, which) -> {
|
||||
viewModel.unblock(recipient.getId());
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setCancelable(true)
|
||||
.create();
|
||||
|
||||
confirmationDialog.setOnShowListener(dialog -> {
|
||||
confirmationDialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.RED);
|
||||
BlockUnblockDialog.showUnblockFor(requireContext(), getViewLifecycleOwner().getLifecycle(), recipient, () -> {
|
||||
viewModel.unblock(recipient.getId());
|
||||
});
|
||||
|
||||
confirmationDialog.show();
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components.settings.conversation.preferences
|
|||
|
||||
import android.content.ClipData
|
||||
import android.content.Context
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
|
@ -9,7 +10,9 @@ import org.thoughtcrime.securesms.R
|
|||
import org.thoughtcrime.securesms.components.settings.PreferenceModel
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.ContextUtil
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingViewHolder
|
||||
|
@ -25,17 +28,25 @@ object BioTextPreference {
|
|||
}
|
||||
|
||||
abstract class BioTextPreferenceModel<T : BioTextPreferenceModel<T>> : PreferenceModel<T>() {
|
||||
abstract fun getHeadlineText(context: Context): String
|
||||
abstract fun getHeadlineText(context: Context): CharSequence
|
||||
abstract fun getSubhead1Text(context: Context): String?
|
||||
abstract fun getSubhead2Text(): String?
|
||||
abstract fun getCompoundDrawable(): Int
|
||||
}
|
||||
|
||||
class RecipientModel(
|
||||
private val recipient: Recipient,
|
||||
) : BioTextPreferenceModel<RecipientModel>() {
|
||||
|
||||
override fun getHeadlineText(context: Context): String = recipient.getDisplayNameOrUsername(context)
|
||||
override fun getHeadlineText(context: Context): CharSequence {
|
||||
val name = recipient.getDisplayNameOrUsername(context)
|
||||
return if (recipient.isReleaseNotes) {
|
||||
SpannableStringBuilder(name).apply {
|
||||
SpanUtil.appendCenteredImageSpan(this, ContextUtil.requireDrawable(context, R.drawable.ic_official_28), 28, 28)
|
||||
}
|
||||
} else {
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSubhead1Text(context: Context): String? {
|
||||
return if (recipient.isReleaseNotes) {
|
||||
|
@ -47,10 +58,6 @@ object BioTextPreference {
|
|||
|
||||
override fun getSubhead2Text(): String? = recipient.e164.transform(PhoneNumberFormatter::prettyPrint).orNull()
|
||||
|
||||
override fun getCompoundDrawable(): Int {
|
||||
return if (recipient.isReleaseNotes) R.drawable.ic_official_28 else 0
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(newItem: RecipientModel): Boolean {
|
||||
return super.areContentsTheSame(newItem) && newItem.recipient.hasSameContent(recipient)
|
||||
}
|
||||
|
@ -64,14 +71,12 @@ object BioTextPreference {
|
|||
val groupTitle: String,
|
||||
val groupMembershipDescription: String?
|
||||
) : BioTextPreferenceModel<GroupModel>() {
|
||||
override fun getHeadlineText(context: Context): String = groupTitle
|
||||
override fun getHeadlineText(context: Context): CharSequence = groupTitle
|
||||
|
||||
override fun getSubhead1Text(context: Context): String? = groupMembershipDescription
|
||||
|
||||
override fun getSubhead2Text(): String? = null
|
||||
|
||||
override fun getCompoundDrawable(): Int = 0
|
||||
|
||||
override fun areContentsTheSame(newItem: GroupModel): Boolean {
|
||||
return super.areContentsTheSame(newItem) &&
|
||||
groupTitle == newItem.groupTitle &&
|
||||
|
@ -91,7 +96,6 @@ object BioTextPreference {
|
|||
|
||||
override fun bind(model: T) {
|
||||
headline.text = model.getHeadlineText(context)
|
||||
headline.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, model.getCompoundDrawable(), 0)
|
||||
|
||||
model.getSubhead1Text(context).let {
|
||||
subhead1.text = it
|
||||
|
|
|
@ -6,17 +6,21 @@ import android.view.MotionEvent
|
|||
import android.view.View
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import io.reactivex.rxjava3.subjects.Subject
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.HidingLinearLayout
|
||||
import org.thoughtcrime.securesms.components.reminder.ReminderView
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentRepository
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture
|
||||
import org.thoughtcrime.securesms.util.views.Stub
|
||||
|
||||
open class ConversationActivity : PassphraseRequiredActivity(), ConversationParentFragment.Callback {
|
||||
open class ConversationActivity : PassphraseRequiredActivity(), ConversationParentFragment.Callback, DonationPaymentComponent {
|
||||
|
||||
private lateinit var fragment: ConversationParentFragment
|
||||
|
||||
|
@ -73,4 +77,7 @@ open class ConversationActivity : PassphraseRequiredActivity(), ConversationPare
|
|||
fun getReminderView(): Stub<ReminderView> {
|
||||
return fragment.reminderView
|
||||
}
|
||||
|
||||
override val donationPaymentRepository: DonationPaymentRepository by lazy { DonationPaymentRepository(this) }
|
||||
override val googlePayResultPublisher: Subject<DonationPaymentComponent.GooglePayResult> = PublishSubject.create()
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ import androidx.core.view.ViewKt;
|
|||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
|
||||
|
@ -1857,7 +1858,12 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
@Override
|
||||
public void onDonateClicked() {
|
||||
if (SignalStore.donationsValues().isLikelyASustainer()) {
|
||||
startActivity(AppSettingsActivity.boost(requireContext()));
|
||||
NavHostFragment navHostFragment = NavHostFragment.create(R.navigation.boosts);
|
||||
|
||||
requireActivity().getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.add(navHostFragment, "boost_nav")
|
||||
.commitNow();
|
||||
} else {
|
||||
startActivity(AppSettingsActivity.subscriptions(requireContext()));
|
||||
}
|
||||
|
|
|
@ -716,7 +716,7 @@ public final class ConversationReactionOverlay extends FrameLayout {
|
|||
|
||||
items.add(new ActionItem(R.drawable.ic_select_24_tinted, getResources().getString(R.string.conversation_selection__menu_multi_select), () -> handleActionItemClicked(Action.MULTISELECT)));
|
||||
|
||||
if (menuState.shouldShowInfoAction()) {
|
||||
if (menuState.shouldShowDetailsAction()) {
|
||||
items.add(new ActionItem(R.drawable.ic_info_tinted_24, getResources().getString(R.string.conversation_selection__menu_message_details), () -> handleActionItemClicked(Action.VIEW_INFO)));
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ final class MenuState {
|
|||
private final boolean resend;
|
||||
private final boolean copy;
|
||||
private final boolean delete;
|
||||
private final boolean info;
|
||||
private final boolean reactions;
|
||||
|
||||
private MenuState(@NonNull Builder builder) {
|
||||
|
@ -33,7 +32,6 @@ final class MenuState {
|
|||
resend = builder.resend;
|
||||
copy = builder.copy;
|
||||
delete = builder.delete;
|
||||
info = builder.info;
|
||||
reactions = builder.reactions;
|
||||
}
|
||||
|
||||
|
@ -65,10 +63,6 @@ final class MenuState {
|
|||
return delete;
|
||||
}
|
||||
|
||||
boolean shouldShowInfoAction() {
|
||||
return info;
|
||||
}
|
||||
|
||||
boolean shouldShowReactions() {
|
||||
return reactions;
|
||||
}
|
||||
|
@ -154,13 +148,13 @@ final class MenuState {
|
|||
((MediaMmsMessageRecord)messageRecord).containsMediaSlide() &&
|
||||
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getStickerSlide() == null)
|
||||
.shouldShowForwardAction(shouldShowForwardAction)
|
||||
.shouldShowDetailsAction(!actionMessage)
|
||||
.shouldShowDetailsAction(!actionMessage && !conversationRecipient.isReleaseNotes())
|
||||
.shouldShowReplyAction(canReplyToMessage(conversationRecipient, actionMessage, messageRecord, shouldShowMessageRequest, isNonAdminInAnnouncementGroup));
|
||||
}
|
||||
|
||||
return builder.shouldShowCopyAction(!actionMessage && !remoteDelete && hasText)
|
||||
.shouldShowDeleteAction(!hasInMemory && onlyContainsCompleteMessages(selectedParts))
|
||||
.shouldShowInfoAction(!conversationRecipient.isReleaseNotes())
|
||||
.shouldShowDetailsAction(!conversationRecipient.isReleaseNotes())
|
||||
.shouldShowReactions(!conversationRecipient.isReleaseNotes())
|
||||
.build();
|
||||
}
|
||||
|
@ -216,7 +210,6 @@ final class MenuState {
|
|||
private boolean resend;
|
||||
private boolean copy;
|
||||
private boolean delete;
|
||||
private boolean info;
|
||||
private boolean reactions;
|
||||
|
||||
@NonNull Builder shouldShowForwardAction(boolean forward) {
|
||||
|
@ -254,11 +247,6 @@ final class MenuState {
|
|||
return this;
|
||||
}
|
||||
|
||||
@NonNull Builder shouldShowInfoAction(boolean info) {
|
||||
this.info = info;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull Builder shouldShowReactions(boolean reactions) {
|
||||
this.reactions = reactions;
|
||||
return this;
|
||||
|
|
|
@ -137,11 +137,13 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
|
|||
val allReleaseNotes: ReleaseNotes? = S3.getAndVerifyObject(MANIFEST, ReleaseNotes::class.java, manifestMd5).result.orNull()
|
||||
|
||||
if (allReleaseNotes != null) {
|
||||
val resolvedNotes: List<FullReleaseNote?> = allReleaseNotes.announcements
|
||||
.filter { it.androidMinVersion.toIntOrNull()?.let { minVersion: Int -> minVersion > values.highestVersionNoteReceived && minVersion <= BuildConfig.CANONICAL_VERSION_CODE } ?: false }
|
||||
val resolvedNotes: List<FullReleaseNote?> = allReleaseNotes.announcements.asSequence()
|
||||
.filter { it.androidMinVersion != null }
|
||||
.filter { it.androidMinVersion!!.toIntOrNull()?.let { minVersion: Int -> minVersion > values.highestVersionNoteReceived && minVersion <= BuildConfig.CANONICAL_VERSION_CODE } ?: false }
|
||||
.filter { it.countries == null || LocaleFeatureFlags.shouldShowReleaseNote(it.uuid, it.countries) }
|
||||
.sortedBy { it.androidMinVersion.toInt() }
|
||||
.sortedBy { it.androidMinVersion!!.toInt() }
|
||||
.map { resolveReleaseNote(it) }
|
||||
.toList()
|
||||
|
||||
if (resolvedNotes.any { it == null }) {
|
||||
Log.w(TAG, "Some release notes did not resolve, aborting.")
|
||||
|
@ -174,7 +176,9 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
|
|||
body = body,
|
||||
threadId = threadId,
|
||||
messageRanges = bodyRangeList.build(),
|
||||
image = note.translation.image
|
||||
image = note.translation.image,
|
||||
imageWidth = note.translation.imageWidth?.toIntOrNull() ?: 0,
|
||||
imageHeight = note.translation.imageHeight?.toIntOrNull() ?: 0
|
||||
)
|
||||
|
||||
SignalDatabase.sms.insertBoostRequestMessage(values.releaseChannelRecipientId!!, threadId)
|
||||
|
@ -186,7 +190,7 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
|
|||
ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.threadId)
|
||||
TrimThreadJob.enqueueAsync(insertResult.threadId)
|
||||
|
||||
highestVersion = max(highestVersion, note.releaseNote.androidMinVersion.toInt())
|
||||
highestVersion = max(highestVersion, note.releaseNote.androidMinVersion!!.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +246,7 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
|
|||
data class ReleaseNote(
|
||||
@JsonProperty val uuid: String,
|
||||
@JsonProperty val countries: String?,
|
||||
@JsonProperty val androidMinVersion: String,
|
||||
@JsonProperty val androidMinVersion: String?,
|
||||
@JsonProperty val link: String?,
|
||||
@JsonProperty val ctaId: String?
|
||||
)
|
||||
|
@ -250,6 +254,8 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
|
|||
data class TranslatedReleaseNote(
|
||||
@JsonProperty val uuid: String,
|
||||
@JsonProperty val image: String?,
|
||||
@JsonProperty val imageWidth: String?,
|
||||
@JsonProperty val imageHeight: String?,
|
||||
@JsonProperty val linkText: String?,
|
||||
@JsonProperty val title: String,
|
||||
@JsonProperty val body: String,
|
||||
|
|
|
@ -4,7 +4,10 @@ import android.app.Activity;
|
|||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -41,7 +44,9 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil;
|
||||
import org.thoughtcrime.securesms.util.ContextUtil;
|
||||
import org.thoughtcrime.securesms.util.DrawableUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.SpanUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
@ -170,16 +175,16 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
|
|||
|
||||
String name = recipient.isSelf() ? requireContext().getString(R.string.note_to_self)
|
||||
: recipient.getDisplayName(requireContext());
|
||||
fullName.setText(name);
|
||||
fullName.setVisibility(TextUtils.isEmpty(name) ? View.GONE : View.VISIBLE);
|
||||
SpannableStringBuilder nameBuilder = new SpannableStringBuilder(name);
|
||||
if (recipient.isSystemContact() && !recipient.isSelf()) {
|
||||
fullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_profile_circle_outline_16, 0);
|
||||
fullName.setCompoundDrawablePadding(ViewUtil.dpToPx(4));
|
||||
TextViewCompat.setCompoundDrawableTintList(fullName, ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.signal_text_primary)));
|
||||
Drawable systemContact = DrawableUtil.tint(ContextUtil.requireDrawable(requireContext(), R.drawable.ic_profile_circle_outline_16),
|
||||
ContextCompat.getColor(requireContext(), R.color.signal_text_primary));
|
||||
SpanUtil.appendCenteredImageSpan(nameBuilder, systemContact, 16, 16);
|
||||
} else if (recipient.isReleaseNotes()) {
|
||||
fullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_official_28, 0);
|
||||
fullName.setCompoundDrawablePadding(ViewUtil.dpToPx(4));
|
||||
SpanUtil.appendCenteredImageSpan(nameBuilder, ContextUtil.requireDrawable(requireContext(), R.drawable.ic_official_28), 28, 28);
|
||||
}
|
||||
fullName.setText(nameBuilder);
|
||||
|
||||
String aboutText = recipient.getCombinedAboutAndEmoji();
|
||||
if (recipient.isReleaseNotes()) {
|
||||
|
|
|
@ -24,6 +24,8 @@ object ReleaseChannel {
|
|||
body: String,
|
||||
threadId: Long,
|
||||
image: String? = null,
|
||||
imageWidth: Int = 0,
|
||||
imageHeight: Int = 0,
|
||||
serverUuid: String? = UUID.randomUUID().toString(),
|
||||
messageRanges: BodyRangeList? = null
|
||||
): MessageDatabase.InsertResult? {
|
||||
|
@ -36,8 +38,8 @@ object ReleaseChannel {
|
|||
null,
|
||||
Optional.absent(),
|
||||
Optional.absent(),
|
||||
0,
|
||||
0,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
Optional.absent(),
|
||||
Optional.of(image),
|
||||
false,
|
||||
|
|
|
@ -127,6 +127,11 @@ public final class SpanUtil {
|
|||
return imageSpan;
|
||||
}
|
||||
|
||||
public static void appendCenteredImageSpan(@NonNull SpannableStringBuilder builder, @NonNull Drawable drawable, int width, int height) {
|
||||
drawable.setBounds(0, 0, ViewUtil.dpToPx(width), ViewUtil.dpToPx(height));
|
||||
builder.append(" ").append(SpanUtil.buildCenteredImageSpan(drawable));
|
||||
}
|
||||
|
||||
public static CharSequence learnMore(@NonNull Context context,
|
||||
@ColorInt int color,
|
||||
@NonNull View.OnClickListener onLearnMoreClicked)
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout="@layout/conversation_item_update_donate" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -7,15 +7,13 @@
|
|||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/bio_preference_headline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:drawablePadding="4dp"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/Signal.Text.Headline.Medium"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
|
|
@ -46,11 +46,12 @@
|
|||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/rbs_full_name"
|
||||
style="@style/Signal.Text.Headline.Medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dsl_settings_gutter"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="@dimen/dsl_settings_gutter"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@color/signal_text_primary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
|
|
|
@ -466,7 +466,9 @@
|
|||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_close_enter"
|
||||
app:popExitAnim="@anim/fragment_close_exit" />
|
||||
app:popExitAnim="@anim/fragment_close_exit"
|
||||
app:popUpTo="@id/app_settings"
|
||||
app:popUpToInclusive="true" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_direct_to_manageDonations"
|
||||
|
|
Ładowanie…
Reference in New Issue