mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-24 18:45:19 +00:00
Use consistent dialog style
This commit is contained in:
commit
96ec733517
@ -0,0 +1,28 @@
|
||||
package org.thoughtcrime.securesms
|
||||
|
||||
import android.content.Context
|
||||
import network.loki.messenger.R
|
||||
|
||||
class DeleteMediaDialog {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(context: Context, recordCount: Int, doDelete: Runnable) = context.showSessionDialog {
|
||||
iconAttribute(R.attr.dialog_alert_icon)
|
||||
title(
|
||||
context.resources.getQuantityString(
|
||||
R.plurals.MediaOverviewActivity_Media_delete_confirm_title,
|
||||
recordCount,
|
||||
recordCount
|
||||
)
|
||||
)
|
||||
text(
|
||||
context.resources.getQuantityString(R.plurals.MediaOverviewActivity_Media_delete_confirm_message,
|
||||
recordCount,
|
||||
recordCount
|
||||
)
|
||||
)
|
||||
button(R.string.delete) { doDelete.run() }
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.thoughtcrime.securesms
|
||||
|
||||
import android.content.Context
|
||||
import network.loki.messenger.R
|
||||
|
||||
class DeleteMediaPreviewDialog {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(context: Context, doDelete: Runnable) {
|
||||
context.showSessionDialog {
|
||||
iconAttribute(R.attr.dialog_alert_icon)
|
||||
title(R.string.MediaPreviewActivity_media_delete_confirmation_title)
|
||||
text(R.string.MediaPreviewActivity_media_delete_confirmation_message)
|
||||
button(R.string.delete) { doDelete.run() }
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.session.libsession.utilities.ExpirationUtil;
|
||||
|
||||
import cn.carbswang.android.numberpickerview.library.NumberPickerView;
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class ExpirationDialog extends AlertDialog {
|
||||
|
||||
protected ExpirationDialog(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
protected ExpirationDialog(Context context, int theme) {
|
||||
super(context, theme);
|
||||
}
|
||||
|
||||
protected ExpirationDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
|
||||
super(context, cancelable, cancelListener);
|
||||
}
|
||||
|
||||
public static void show(final Context context,
|
||||
final int currentExpiration,
|
||||
final @NonNull OnClickListener listener)
|
||||
{
|
||||
final View view = createNumberPickerView(context, currentExpiration);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(context.getString(R.string.ExpirationDialog_disappearing_messages));
|
||||
builder.setView(view);
|
||||
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
int selected = ((NumberPickerView)view.findViewById(R.id.expiration_number_picker)).getValue();
|
||||
listener.onClick(context.getResources().getIntArray(R.array.expiration_times)[selected]);
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private static View createNumberPickerView(final Context context, final int currentExpiration) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
final View view = inflater.inflate(R.layout.expiration_dialog, null);
|
||||
final NumberPickerView numberPickerView = view.findViewById(R.id.expiration_number_picker);
|
||||
final TextView textView = view.findViewById(R.id.expiration_details);
|
||||
final int[] expirationTimes = context.getResources().getIntArray(R.array.expiration_times);
|
||||
final String[] expirationDisplayValues = new String[expirationTimes.length];
|
||||
|
||||
int selectedIndex = expirationTimes.length - 1;
|
||||
|
||||
for (int i=0;i<expirationTimes.length;i++) {
|
||||
expirationDisplayValues[i] = ExpirationUtil.getExpirationDisplayValue(context, expirationTimes[i]);
|
||||
|
||||
if ((currentExpiration >= expirationTimes[i]) &&
|
||||
(i == expirationTimes.length -1 || currentExpiration < expirationTimes[i+1])) {
|
||||
selectedIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
numberPickerView.setDisplayedValues(expirationDisplayValues);
|
||||
numberPickerView.setMinValue(0);
|
||||
numberPickerView.setMaxValue(expirationTimes.length-1);
|
||||
|
||||
NumberPickerView.OnValueChangeListener listener = (picker, oldVal, newVal) -> {
|
||||
if (newVal == 0) {
|
||||
textView.setText(R.string.ExpirationDialog_your_messages_will_not_expire);
|
||||
} else {
|
||||
textView.setText(context.getString(R.string.ExpirationDialog_your_messages_will_disappear_s_after_they_have_been_seen, picker.getDisplayedValues()[newVal]));
|
||||
}
|
||||
};
|
||||
|
||||
numberPickerView.setOnValueChangedListener(listener);
|
||||
numberPickerView.setValue(selectedIndex);
|
||||
listener.onValueChange(numberPickerView, selectedIndex, selectedIndex);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public interface OnClickListener {
|
||||
public void onClick(int expirationTime);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package org.thoughtcrime.securesms
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import cn.carbswang.android.numberpickerview.library.NumberPickerView
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.ExpirationUtil
|
||||
|
||||
fun Context.showExpirationDialog(
|
||||
expiration: Int,
|
||||
onExpirationTime: (Int) -> Unit
|
||||
): AlertDialog {
|
||||
val view = LayoutInflater.from(this).inflate(R.layout.expiration_dialog, null)
|
||||
val numberPickerView = view.findViewById<NumberPickerView>(R.id.expiration_number_picker)
|
||||
|
||||
fun updateText(index: Int) {
|
||||
view.findViewById<TextView>(R.id.expiration_details).text = when (index) {
|
||||
0 -> getString(R.string.ExpirationDialog_your_messages_will_not_expire)
|
||||
else -> getString(
|
||||
R.string.ExpirationDialog_your_messages_will_disappear_s_after_they_have_been_seen,
|
||||
numberPickerView.displayedValues[index]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val expirationTimes = resources.getIntArray(R.array.expiration_times)
|
||||
val expirationDisplayValues = expirationTimes
|
||||
.map { ExpirationUtil.getExpirationDisplayValue(this, it) }
|
||||
.toTypedArray()
|
||||
|
||||
val selectedIndex = expirationTimes.run { indexOfFirst { it >= expiration }.coerceIn(indices) }
|
||||
|
||||
numberPickerView.apply {
|
||||
displayedValues = expirationDisplayValues
|
||||
minValue = 0
|
||||
maxValue = expirationTimes.lastIndex
|
||||
setOnValueChangedListener { _, _, index -> updateText(index) }
|
||||
value = selectedIndex
|
||||
}
|
||||
|
||||
updateText(selectedIndex)
|
||||
|
||||
return showSessionDialog {
|
||||
title(getString(R.string.ExpirationDialog_disappearing_messages))
|
||||
view(view)
|
||||
okButton { onExpirationTime(numberPickerView.let { expirationTimes[it.value] }) }
|
||||
cancelButton()
|
||||
}
|
||||
}
|
@ -76,6 +76,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import kotlin.Unit;
|
||||
import network.loki.messenger.R;
|
||||
|
||||
/**
|
||||
@ -318,9 +319,9 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
||||
@SuppressWarnings("CodeBlock2Expr")
|
||||
@SuppressLint({"InlinedApi", "StaticFieldLeak"})
|
||||
private void handleSaveMedia(@NonNull Collection<MediaDatabase.MediaRecord> mediaRecords) {
|
||||
final Context context = getContext();
|
||||
final Context context = requireContext();
|
||||
|
||||
SaveAttachmentTask.showWarningDialog(context, (dialogInterface, which) -> {
|
||||
SaveAttachmentTask.showWarningDialog(context, mediaRecords.size(), () -> {
|
||||
Permissions.with(this)
|
||||
.request(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
.maxSdkVersion(Build.VERSION_CODES.P)
|
||||
@ -362,7 +363,8 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
||||
}.execute();
|
||||
})
|
||||
.execute();
|
||||
}, mediaRecords.size());
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
private void sendMediaSavedNotificationIfNeeded() {
|
||||
@ -374,41 +376,26 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void handleDeleteMedia(@NonNull Collection<MediaDatabase.MediaRecord> mediaRecords) {
|
||||
int recordCount = mediaRecords.size();
|
||||
Resources res = getContext().getResources();
|
||||
String confirmTitle = res.getQuantityString(R.plurals.MediaOverviewActivity_Media_delete_confirm_title,
|
||||
recordCount,
|
||||
recordCount);
|
||||
String confirmMessage = res.getQuantityString(R.plurals.MediaOverviewActivity_Media_delete_confirm_message,
|
||||
recordCount,
|
||||
recordCount);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setIconAttribute(R.attr.dialog_alert_icon);
|
||||
builder.setTitle(confirmTitle);
|
||||
builder.setMessage(confirmMessage);
|
||||
builder.setCancelable(true);
|
||||
|
||||
builder.setPositiveButton(R.string.delete, (dialogInterface, i) -> {
|
||||
new ProgressDialogAsyncTask<MediaDatabase.MediaRecord, Void, Void>(getContext(),
|
||||
R.string.MediaOverviewActivity_Media_delete_progress_title,
|
||||
R.string.MediaOverviewActivity_Media_delete_progress_message)
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(MediaDatabase.MediaRecord... records) {
|
||||
if (records == null || records.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (MediaDatabase.MediaRecord record : records) {
|
||||
AttachmentUtil.deleteAttachment(getContext(), record.getAttachment());
|
||||
}
|
||||
DeleteMediaDialog.show(
|
||||
requireContext(),
|
||||
recordCount,
|
||||
() -> new ProgressDialogAsyncTask<MediaDatabase.MediaRecord, Void, Void>(
|
||||
requireContext(),
|
||||
R.string.MediaOverviewActivity_Media_delete_progress_title,
|
||||
R.string.MediaOverviewActivity_Media_delete_progress_message) {
|
||||
@Override
|
||||
protected Void doInBackground(MediaDatabase.MediaRecord... records) {
|
||||
if (records == null || records.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}.execute(mediaRecords.toArray(new MediaDatabase.MediaRecord[mediaRecords.size()]));
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.show();
|
||||
for (MediaDatabase.MediaRecord record : records) {
|
||||
AttachmentUtil.deleteAttachment(getContext(), record.getAttachment());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}.execute(mediaRecords.toArray(new MediaDatabase.MediaRecord[mediaRecords.size()])));
|
||||
}
|
||||
|
||||
private void handleSelectAllMedia() {
|
||||
|
@ -85,6 +85,7 @@ import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import kotlin.Unit;
|
||||
import network.loki.messenger.R;
|
||||
|
||||
/**
|
||||
@ -416,7 +417,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
MediaItem mediaItem = getCurrentMediaItem();
|
||||
if (mediaItem == null) return;
|
||||
|
||||
SaveAttachmentTask.showWarningDialog(this, (dialogInterface, i) -> {
|
||||
SaveAttachmentTask.showWarningDialog(this, 1, () -> {
|
||||
Permissions.with(this)
|
||||
.request(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
.maxSdkVersion(Build.VERSION_CODES.P)
|
||||
@ -433,6 +434,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
}
|
||||
})
|
||||
.execute();
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
@ -449,29 +451,20 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setIconAttribute(R.attr.dialog_alert_icon);
|
||||
builder.setTitle(R.string.MediaPreviewActivity_media_delete_confirmation_title);
|
||||
builder.setMessage(R.string.MediaPreviewActivity_media_delete_confirmation_message);
|
||||
builder.setCancelable(true);
|
||||
|
||||
builder.setPositiveButton(R.string.delete, (dialogInterface, which) -> {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
if (mediaItem.attachment == null) {
|
||||
return null;
|
||||
}
|
||||
AttachmentUtil.deleteAttachment(MediaPreviewActivity.this.getApplicationContext(),
|
||||
mediaItem.attachment);
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
DeleteMediaPreviewDialog.show(this, () -> {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
DatabaseAttachment attachment = mediaItem.attachment;
|
||||
if (attachment != null) {
|
||||
AttachmentUtil.deleteAttachment(getApplicationContext(), attachment);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
|
||||
finish();
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,56 +0,0 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class MuteDialog extends AlertDialog {
|
||||
|
||||
|
||||
protected MuteDialog(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
protected MuteDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
|
||||
super(context, cancelable, cancelListener);
|
||||
}
|
||||
|
||||
protected MuteDialog(Context context, int theme) {
|
||||
super(context, theme);
|
||||
}
|
||||
|
||||
public static void show(final Context context, final @NonNull MuteSelectionListener listener) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.MuteDialog_mute_notifications);
|
||||
builder.setItems(R.array.mute_durations, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, final int which) {
|
||||
final long muteUntil;
|
||||
|
||||
switch (which) {
|
||||
case 1: muteUntil = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(2); break;
|
||||
case 2: muteUntil = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1); break;
|
||||
case 3: muteUntil = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7); break;
|
||||
case 4: muteUntil = Long.MAX_VALUE; break;
|
||||
default: muteUntil = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1); break;
|
||||
}
|
||||
|
||||
listener.onMuted(muteUntil);
|
||||
}
|
||||
});
|
||||
|
||||
builder.show();
|
||||
|
||||
}
|
||||
|
||||
public interface MuteSelectionListener {
|
||||
public void onMuted(long until);
|
||||
}
|
||||
|
||||
}
|
27
app/src/main/java/org/thoughtcrime/securesms/MuteDialog.kt
Normal file
27
app/src/main/java/org/thoughtcrime/securesms/MuteDialog.kt
Normal file
@ -0,0 +1,27 @@
|
||||
package org.thoughtcrime.securesms
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import network.loki.messenger.R
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
fun showMuteDialog(
|
||||
context: Context,
|
||||
onMuteDuration: (Long) -> Unit
|
||||
): AlertDialog = context.showSessionDialog {
|
||||
title(R.string.MuteDialog_mute_notifications)
|
||||
items(Option.values().map { it.stringRes }.map(context::getString).toTypedArray()) {
|
||||
onMuteDuration(Option.values()[it].getTime())
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Option(@StringRes val stringRes: Int, val getTime: () -> Long) {
|
||||
ONE_HOUR(R.string.arrays__mute_for_one_hour, duration = TimeUnit.HOURS.toMillis(1)),
|
||||
TWO_HOURS(R.string.arrays__mute_for_two_hours, duration = TimeUnit.DAYS.toMillis(2)),
|
||||
ONE_DAY(R.string.arrays__mute_for_one_day, duration = TimeUnit.DAYS.toMillis(1)),
|
||||
SEVEN_DAYS(R.string.arrays__mute_for_seven_days, duration = TimeUnit.DAYS.toMillis(7)),
|
||||
FOREVER(R.string.arrays__mute_forever, getTime = { Long.MAX_VALUE });
|
||||
|
||||
constructor(@StringRes stringRes: Int, duration: Long): this(stringRes, { System.currentTimeMillis() + duration })
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
package org.thoughtcrime.securesms
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.LinearLayout.VERTICAL
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.annotation.StyleRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.setMargins
|
||||
import androidx.core.view.setPadding
|
||||
import androidx.core.view.updateMargins
|
||||
import androidx.fragment.app.Fragment
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.util.toPx
|
||||
|
||||
|
||||
@DslMarker
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
|
||||
annotation class DialogDsl
|
||||
|
||||
@DialogDsl
|
||||
class SessionDialogBuilder(val context: Context) {
|
||||
|
||||
private val dp20 = toPx(20, context.resources)
|
||||
private val dp40 = toPx(40, context.resources)
|
||||
|
||||
private val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(context)
|
||||
|
||||
private var dialog: AlertDialog? = null
|
||||
private fun dismiss() = dialog?.dismiss()
|
||||
|
||||
private val topView = LinearLayout(context).apply { orientation = VERTICAL }
|
||||
.also(dialogBuilder::setCustomTitle)
|
||||
private val contentView = LinearLayout(context).apply { orientation = VERTICAL }
|
||||
private val buttonLayout = LinearLayout(context)
|
||||
|
||||
private val root = LinearLayout(context).apply { orientation = VERTICAL }
|
||||
.also(dialogBuilder::setView)
|
||||
.apply {
|
||||
addView(contentView)
|
||||
addView(buttonLayout)
|
||||
}
|
||||
|
||||
fun title(@StringRes id: Int) = title(context.getString(id))
|
||||
|
||||
fun title(text: CharSequence?) = title(text?.toString())
|
||||
fun title(text: String?) {
|
||||
text(text, R.style.TextAppearance_AppCompat_Title) { setPadding(dp20) }
|
||||
}
|
||||
|
||||
fun text(@StringRes id: Int, style: Int = 0) = text(context.getString(id), style)
|
||||
fun text(text: CharSequence?, @StyleRes style: Int = 0) {
|
||||
text(text, style) {
|
||||
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
||||
.apply { updateMargins(dp40, 0, dp40, dp20) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun text(text: CharSequence?, @StyleRes style: Int, modify: TextView.() -> Unit) {
|
||||
text ?: return
|
||||
TextView(context, null, 0, style)
|
||||
.apply {
|
||||
setText(text)
|
||||
textAlignment = View.TEXT_ALIGNMENT_CENTER
|
||||
modify()
|
||||
}.let(topView::addView)
|
||||
}
|
||||
|
||||
fun view(view: View) = contentView.addView(view)
|
||||
|
||||
fun view(@LayoutRes layout: Int): View = LayoutInflater.from(context).inflate(layout, contentView)
|
||||
|
||||
fun iconAttribute(@AttrRes icon: Int): AlertDialog.Builder = dialogBuilder.setIconAttribute(icon)
|
||||
|
||||
fun singleChoiceItems(
|
||||
options: Collection<String>,
|
||||
currentSelected: Int = 0,
|
||||
onSelect: (Int) -> Unit
|
||||
) = singleChoiceItems(options.toTypedArray(), currentSelected, onSelect)
|
||||
|
||||
fun singleChoiceItems(
|
||||
options: Array<String>,
|
||||
currentSelected: Int = 0,
|
||||
onSelect: (Int) -> Unit
|
||||
): AlertDialog.Builder = dialogBuilder.setSingleChoiceItems(
|
||||
options,
|
||||
currentSelected
|
||||
) { dialog, it -> onSelect(it); dialog.dismiss() }
|
||||
|
||||
fun items(
|
||||
options: Array<String>,
|
||||
onSelect: (Int) -> Unit
|
||||
): AlertDialog.Builder = dialogBuilder.setItems(
|
||||
options,
|
||||
) { dialog, it -> onSelect(it); dialog.dismiss() }
|
||||
|
||||
fun destructiveButton(
|
||||
@StringRes text: Int,
|
||||
@StringRes contentDescription: Int,
|
||||
listener: () -> Unit = {}
|
||||
) = button(
|
||||
text,
|
||||
contentDescription,
|
||||
R.style.Widget_Session_Button_Dialog_DestructiveText,
|
||||
listener
|
||||
)
|
||||
|
||||
fun okButton(listener: (() -> Unit) = {}) = button(android.R.string.ok, listener = listener)
|
||||
fun cancelButton(listener: (() -> Unit) = {}) = button(android.R.string.cancel, R.string.AccessibilityId_cancel_button, listener = listener)
|
||||
|
||||
fun button(
|
||||
@StringRes text: Int,
|
||||
@StringRes contentDescriptionRes: Int = text,
|
||||
@StyleRes style: Int = R.style.Widget_Session_Button_Dialog_UnimportantText,
|
||||
listener: (() -> Unit) = {}
|
||||
) = Button(context, null, 0, style).apply {
|
||||
setText(text)
|
||||
contentDescription = resources.getString(contentDescriptionRes)
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1f)
|
||||
.apply { setMargins(toPx(20, resources)) }
|
||||
setOnClickListener {
|
||||
listener.invoke()
|
||||
dismiss()
|
||||
}
|
||||
}.let(buttonLayout::addView)
|
||||
|
||||
fun create(): AlertDialog = dialogBuilder.create().also { dialog = it }
|
||||
fun show(): AlertDialog = dialogBuilder.show().also { dialog = it }
|
||||
}
|
||||
|
||||
fun Context.showSessionDialog(build: SessionDialogBuilder.() -> Unit): AlertDialog =
|
||||
SessionDialogBuilder(this).apply { build() }.show()
|
||||
|
||||
fun Fragment.showSessionDialog(build: SessionDialogBuilder.() -> Unit): AlertDialog =
|
||||
SessionDialogBuilder(requireContext()).apply { build() }.show()
|
||||
fun Fragment.createSessionDialog(build: SessionDialogBuilder.() -> Unit): AlertDialog =
|
||||
SessionDialogBuilder(requireContext()).apply { build() }.create()
|
@ -20,8 +20,8 @@ import android.widget.RelativeLayout
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.DimenRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@ -70,7 +70,6 @@ import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.guava.Optional
|
||||
import org.session.libsignal.utilities.hexEncodedPrivateKey
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.ExpirationDialog
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.attachments.ScreenshotObserver
|
||||
import org.thoughtcrime.securesms.audio.AudioRecorder
|
||||
@ -112,6 +111,8 @@ import org.thoughtcrime.securesms.mms.*
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.reactions.ReactionsDialogFragment
|
||||
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiDialogFragment
|
||||
import org.thoughtcrime.securesms.showExpirationDialog
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.util.*
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
@ -406,8 +407,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
push(intent, false)
|
||||
}
|
||||
|
||||
override fun showDialog(baseDialog: BaseDialog, tag: String?) {
|
||||
baseDialog.show(supportFragmentManager, tag)
|
||||
override fun showDialog(dialogFragment: DialogFragment, tag: String?) {
|
||||
dialogFragment.show(supportFragmentManager, tag)
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, bundle: Bundle?): Loader<Cursor> {
|
||||
@ -965,21 +966,18 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
}
|
||||
|
||||
override fun block(deleteThread: Boolean) {
|
||||
val title = R.string.RecipientPreferenceActivity_block_this_contact_question
|
||||
val message = R.string.RecipientPreferenceActivity_you_will_no_longer_receive_messages_and_calls_from_this_contact
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
.setTitle(title)
|
||||
.setMessage(message)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.RecipientPreferenceActivity_block) { _, _ ->
|
||||
showSessionDialog {
|
||||
title(R.string.RecipientPreferenceActivity_block_this_contact_question)
|
||||
text(R.string.RecipientPreferenceActivity_you_will_no_longer_receive_messages_and_calls_from_this_contact)
|
||||
destructiveButton(R.string.RecipientPreferenceActivity_block, R.string.AccessibilityId_block_confirm) {
|
||||
viewModel.block(this@ConversationActivityV2)
|
||||
if (deleteThread) {
|
||||
viewModel.deleteThread()
|
||||
finish()
|
||||
}
|
||||
}.show()
|
||||
val button = dialog.getButton(DialogInterface.BUTTON_POSITIVE)
|
||||
button.setContentDescription("Confirm block")
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
|
||||
override fun copySessionID(sessionId: String) {
|
||||
@ -1006,28 +1004,27 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
val group = groupDb.getGroup(thread.address.toGroupString()).orNull()
|
||||
if (group?.isActive == false) { return }
|
||||
}
|
||||
ExpirationDialog.show(this, thread.expireMessages) { expirationTime: Int ->
|
||||
showExpirationDialog(thread.expireMessages) { expirationTime ->
|
||||
recipientDb.setExpireMessages(thread, expirationTime)
|
||||
val message = ExpirationTimerUpdate(expirationTime)
|
||||
message.recipient = thread.address.serialize()
|
||||
message.sentTimestamp = SnodeAPI.nowWithOffset
|
||||
val expiringMessageManager = ApplicationContext.getInstance(this).expiringMessageManager
|
||||
expiringMessageManager.setExpirationTimer(message)
|
||||
ApplicationContext.getInstance(this).expiringMessageManager.setExpirationTimer(message)
|
||||
MessageSender.send(message, thread.address)
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
}
|
||||
|
||||
override fun unblock() {
|
||||
val title = R.string.ConversationActivity_unblock_this_contact_question
|
||||
val message = R.string.ConversationActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(title)
|
||||
.setMessage(message)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ConversationActivity_unblock) { _, _ ->
|
||||
viewModel.unblock(this@ConversationActivityV2)
|
||||
}.show()
|
||||
showSessionDialog {
|
||||
title(R.string.ConversationActivity_unblock_this_contact_question)
|
||||
text(R.string.ConversationActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact)
|
||||
destructiveButton(
|
||||
R.string.ConversationActivity_unblock,
|
||||
R.string.AccessibilityId_block_confirm
|
||||
) { viewModel.unblock(this@ConversationActivityV2) }
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
|
||||
// `position` is the adapter position; not the visual position
|
||||
@ -1468,23 +1465,22 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
private fun showGIFPicker() {
|
||||
val hasSeenGIFMetaDataWarning: Boolean = textSecurePreferences.hasSeenGIFMetaDataWarning()
|
||||
if (!hasSeenGIFMetaDataWarning) {
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle(R.string.giphy_permission_title)
|
||||
builder.setMessage(R.string.giphy_permission_message)
|
||||
builder.setPositiveButton(R.string.continue_2) { dialog: DialogInterface, _: Int ->
|
||||
textSecurePreferences.setHasSeenGIFMetaDataWarning()
|
||||
AttachmentManager.selectGif(this, PICK_GIF)
|
||||
dialog.dismiss()
|
||||
showSessionDialog {
|
||||
title(R.string.giphy_permission_title)
|
||||
text(R.string.giphy_permission_message)
|
||||
button(R.string.continue_2) {
|
||||
textSecurePreferences.setHasSeenGIFMetaDataWarning()
|
||||
selectGif()
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
builder.setNegativeButton(R.string.cancel) { dialog: DialogInterface, _: Int ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
builder.create().show()
|
||||
} else {
|
||||
AttachmentManager.selectGif(this, PICK_GIF)
|
||||
selectGif()
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectGif() = AttachmentManager.selectGif(this, PICK_GIF)
|
||||
|
||||
private fun showDocumentPicker() {
|
||||
AttachmentManager.selectDocument(this, PICK_DOCUMENT)
|
||||
}
|
||||
@ -1631,35 +1627,23 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
val allHasHash = messages.all { lokiMessageDb.getMessageServerHash(it.id) != null }
|
||||
if (recipient.isOpenGroupRecipient) {
|
||||
val messageCount = 1
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle(resources.getQuantityString(R.plurals.ConversationFragment_delete_selected_messages, messageCount, messageCount))
|
||||
builder.setMessage(resources.getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messageCount, messageCount))
|
||||
builder.setCancelable(true)
|
||||
builder.setPositiveButton(R.string.delete) { _, _ ->
|
||||
for (message in messages) {
|
||||
viewModel.deleteForEveryone(message)
|
||||
}
|
||||
endActionMode()
|
||||
|
||||
showSessionDialog {
|
||||
title(resources.getQuantityString(R.plurals.ConversationFragment_delete_selected_messages, messageCount, messageCount))
|
||||
text(resources.getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messageCount, messageCount))
|
||||
button(R.string.delete) { messages.forEach(viewModel::deleteForEveryone); endActionMode() }
|
||||
cancelButton { endActionMode() }
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
endActionMode()
|
||||
}
|
||||
builder.show()
|
||||
} else if (allSentByCurrentUser && allHasHash) {
|
||||
val bottomSheet = DeleteOptionsBottomSheet()
|
||||
bottomSheet.recipient = recipient
|
||||
bottomSheet.onDeleteForMeTapped = {
|
||||
for (message in messages) {
|
||||
viewModel.deleteLocally(message)
|
||||
}
|
||||
messages.forEach(viewModel::deleteLocally)
|
||||
bottomSheet.dismiss()
|
||||
endActionMode()
|
||||
}
|
||||
bottomSheet.onDeleteForEveryoneTapped = {
|
||||
for (message in messages) {
|
||||
viewModel.deleteForEveryone(message)
|
||||
}
|
||||
messages.forEach(viewModel::deleteForEveryone)
|
||||
bottomSheet.dismiss()
|
||||
endActionMode()
|
||||
}
|
||||
@ -1670,54 +1654,32 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
bottomSheet.show(supportFragmentManager, bottomSheet.tag)
|
||||
} else {
|
||||
val messageCount = 1
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle(resources.getQuantityString(R.plurals.ConversationFragment_delete_selected_messages, messageCount, messageCount))
|
||||
builder.setMessage(resources.getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messageCount, messageCount))
|
||||
builder.setCancelable(true)
|
||||
builder.setPositiveButton(R.string.delete) { _, _ ->
|
||||
for (message in messages) {
|
||||
viewModel.deleteLocally(message)
|
||||
}
|
||||
endActionMode()
|
||||
|
||||
showSessionDialog {
|
||||
title(resources.getQuantityString(R.plurals.ConversationFragment_delete_selected_messages, messageCount, messageCount))
|
||||
text(resources.getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messageCount, messageCount))
|
||||
button(R.string.delete) { messages.forEach(viewModel::deleteLocally); endActionMode() }
|
||||
cancelButton(::endActionMode)
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
endActionMode()
|
||||
}
|
||||
builder.show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun banUser(messages: Set<MessageRecord>) {
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle(R.string.ConversationFragment_ban_selected_user)
|
||||
builder.setMessage("This will ban the selected user from this room. It won't ban them from other rooms.")
|
||||
builder.setCancelable(true)
|
||||
builder.setPositiveButton(R.string.ban) { _, _ ->
|
||||
viewModel.banUser(messages.first().individualRecipient)
|
||||
endActionMode()
|
||||
showSessionDialog {
|
||||
title(R.string.ConversationFragment_ban_selected_user)
|
||||
text("This will ban the selected user from this room. It won't ban them from other rooms.")
|
||||
button(R.string.ban) { viewModel.banUser(messages.first().individualRecipient); endActionMode() }
|
||||
cancelButton(::endActionMode)
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
endActionMode()
|
||||
}
|
||||
builder.show()
|
||||
}
|
||||
|
||||
override fun banAndDeleteAll(messages: Set<MessageRecord>) {
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle(R.string.ConversationFragment_ban_selected_user)
|
||||
builder.setMessage("This will ban the selected user from this room and delete all messages sent by them. It won't ban them from other rooms or delete the messages they sent there.")
|
||||
builder.setCancelable(true)
|
||||
builder.setPositiveButton(R.string.ban) { _, _ ->
|
||||
viewModel.banAndDeleteAll(messages.first().individualRecipient)
|
||||
endActionMode()
|
||||
showSessionDialog {
|
||||
title(R.string.ConversationFragment_ban_selected_user)
|
||||
text("This will ban the selected user from this room and delete all messages sent by them. It won't ban them from other rooms or delete the messages they sent there.")
|
||||
button(R.string.ban) { viewModel.banAndDeleteAll(messages.first().individualRecipient); endActionMode() }
|
||||
cancelButton(::endActionMode)
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
endActionMode()
|
||||
}
|
||||
builder.show()
|
||||
}
|
||||
|
||||
override fun copyMessages(messages: Set<MessageRecord>) {
|
||||
@ -1781,7 +1743,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
|
||||
override fun saveAttachment(messages: Set<MessageRecord>) {
|
||||
val message = messages.first() as MmsMessageRecord
|
||||
SaveAttachmentTask.showWarningDialog(this, { _, _ ->
|
||||
SaveAttachmentTask.showWarningDialog(this) {
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
.maxSdkVersion(Build.VERSION_CODES.P)
|
||||
@ -1809,7 +1771,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
Toast.LENGTH_LONG).show()
|
||||
}
|
||||
.execute()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun reply(messages: Set<MessageRecord>) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
@ -31,6 +30,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.preferences.PrivacySettingsActivity
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
|
||||
class ConversationAdapter(
|
||||
context: Context,
|
||||
@ -146,17 +146,15 @@ class ConversationAdapter(
|
||||
viewHolder.view.bind(message, messageBefore)
|
||||
if (message.isCallLog && message.isFirstMissedCall) {
|
||||
viewHolder.view.setOnClickListener {
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(R.string.CallNotificationBuilder_first_call_title)
|
||||
.setMessage(R.string.CallNotificationBuilder_first_call_message)
|
||||
.setPositiveButton(R.string.activity_settings_title) { _, _ ->
|
||||
val intent = Intent(context, PrivacySettingsActivity::class.java)
|
||||
context.startActivity(intent)
|
||||
context.showSessionDialog {
|
||||
title(R.string.CallNotificationBuilder_first_call_title)
|
||||
text(R.string.CallNotificationBuilder_first_call_message)
|
||||
button(R.string.activity_settings_title) {
|
||||
Intent(context, PrivacySettingsActivity::class.java)
|
||||
.let(context::startActivity)
|
||||
}
|
||||
.setNeutralButton(R.string.cancel) { d, _ ->
|
||||
d.dismiss()
|
||||
}
|
||||
.show()
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
viewHolder.view.setOnClickListener(null)
|
||||
|
@ -1,42 +1,41 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.app.Dialog
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.DialogBlockedBinding
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
|
||||
/** Shown upon sending a message to a user that's blocked. */
|
||||
class BlockedDialog(private val recipient: Recipient, private val context: Context) : BaseDialog() {
|
||||
class BlockedDialog(private val recipient: Recipient, private val context: Context) : DialogFragment() {
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
val binding = DialogBlockedBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
val contactDB = DatabaseComponent.get(requireContext()).sessionContactDatabase()
|
||||
val sessionID = recipient.address.toString()
|
||||
val contact = contactDB.getContactWithSessionID(sessionID)
|
||||
val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID
|
||||
val title = resources.getString(R.string.dialog_blocked_title, name)
|
||||
binding.blockedTitleTextView.text = title
|
||||
|
||||
val explanation = resources.getString(R.string.dialog_blocked_explanation, name)
|
||||
val spannable = SpannableStringBuilder(explanation)
|
||||
val startIndex = explanation.indexOf(name)
|
||||
spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
binding.blockedExplanationTextView.text = spannable
|
||||
binding.cancelButton.setOnClickListener { dismiss() }
|
||||
binding.unblockButton.setOnClickListener { unblock() }
|
||||
builder.setView(binding.root)
|
||||
|
||||
title(resources.getString(R.string.dialog_blocked_title, name))
|
||||
text(spannable)
|
||||
button(R.string.ConversationActivity_unblock) { unblock() }
|
||||
cancelButton { dismiss() }
|
||||
}
|
||||
|
||||
private fun unblock() {
|
||||
@ -48,4 +47,4 @@ class BlockedDialog(private val recipient: Recipient, private val context: Conte
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.DialogDownloadBinding
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.jobs.AttachmentDownloadJob
|
||||
import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
import org.thoughtcrime.securesms.database.SessionContactDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
import javax.inject.Inject
|
||||
@ -21,25 +21,24 @@ import javax.inject.Inject
|
||||
/** Shown when receiving media from a contact for the first time, to confirm that
|
||||
* they are to be trusted and files sent by them are to be downloaded. */
|
||||
@AndroidEntryPoint
|
||||
class DownloadDialog(private val recipient: Recipient) : BaseDialog() {
|
||||
class DownloadDialog(private val recipient: Recipient) : DialogFragment() {
|
||||
|
||||
@Inject lateinit var contactDB: SessionContactDatabase
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
val binding = DialogDownloadBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
val sessionID = recipient.address.toString()
|
||||
val contact = contactDB.getContactWithSessionID(sessionID)
|
||||
val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID
|
||||
val title = resources.getString(R.string.dialog_download_title, name)
|
||||
binding.downloadTitleTextView.text = title
|
||||
title(resources.getString(R.string.dialog_download_title, name))
|
||||
|
||||
val explanation = resources.getString(R.string.dialog_download_explanation, name)
|
||||
val spannable = SpannableStringBuilder(explanation)
|
||||
val startIndex = explanation.indexOf(name)
|
||||
spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
binding.downloadExplanationTextView.text = spannable
|
||||
binding.cancelButton.setOnClickListener { dismiss() }
|
||||
binding.downloadButton.setOnClickListener { trust() }
|
||||
builder.setView(binding.root)
|
||||
text(spannable)
|
||||
|
||||
button(R.string.dialog_download_button_title, R.string.AccessibilityId_download_media) { trust() }
|
||||
cancelButton { dismiss() }
|
||||
}
|
||||
|
||||
private fun trust() {
|
||||
@ -50,4 +49,4 @@ class DownloadDialog(private val recipient: Recipient) : BaseDialog() {
|
||||
JobQueue.shared.resumePendingJobs(AttachmentDownloadJob.KEY)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,41 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.DialogJoinOpenGroupBinding
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.utilities.OpenGroupUrlParser
|
||||
import org.session.libsignal.utilities.ThreadUtils
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
import org.thoughtcrime.securesms.groups.OpenGroupManager
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
|
||||
/** Shown upon tapping an open group invitation. */
|
||||
class JoinOpenGroupDialog(private val name: String, private val url: String) : BaseDialog() {
|
||||
class JoinOpenGroupDialog(private val name: String, private val url: String) : DialogFragment() {
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
val binding = DialogJoinOpenGroupBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
val title = resources.getString(R.string.dialog_join_open_group_title, name)
|
||||
binding.joinOpenGroupTitleTextView.text = title
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
title(resources.getString(R.string.dialog_join_open_group_title, name))
|
||||
val explanation = resources.getString(R.string.dialog_join_open_group_explanation, name)
|
||||
val spannable = SpannableStringBuilder(explanation)
|
||||
val startIndex = explanation.indexOf(name)
|
||||
spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
binding.joinOpenGroupExplanationTextView.text = spannable
|
||||
binding.cancelButton.setOnClickListener { dismiss() }
|
||||
binding.joinButton.setOnClickListener { join() }
|
||||
builder.setView(binding.root)
|
||||
text(spannable)
|
||||
cancelButton { dismiss() }
|
||||
button(R.string.open_group_invitation_view__join_accessibility_description) { join() }
|
||||
}
|
||||
|
||||
private fun join() {
|
||||
val openGroup = OpenGroupUrlParser.parseUrl(url)
|
||||
val activity = requireContext() as AppCompatActivity
|
||||
val activity = requireActivity()
|
||||
ThreadUtils.queue {
|
||||
try {
|
||||
OpenGroupManager.add(openGroup.server, openGroup.room, openGroup.serverPublicKey, activity)
|
||||
openGroup.apply { OpenGroupManager.add(server, room, serverPublicKey, activity) }
|
||||
MessagingModuleConfiguration.shared.storage.onOpenGroupAdded(openGroup.server)
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(activity)
|
||||
} catch (e: Exception) {
|
||||
@ -48,4 +44,4 @@ class JoinOpenGroupDialog(private val name: String, private val url: String) : B
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,21 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import network.loki.messenger.databinding.DialogLinkPreviewBinding
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
|
||||
/** Shown the first time the user inputs a URL that could generate a link preview, to
|
||||
* let them know that Session offers the ability to send and receive link previews. */
|
||||
class LinkPreviewDialog(private val onEnabled: () -> Unit) : BaseDialog() {
|
||||
class LinkPreviewDialog(private val onEnabled: () -> Unit) : DialogFragment() {
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
val binding = DialogLinkPreviewBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
binding.cancelButton.setOnClickListener { dismiss() }
|
||||
binding.enableLinkPreviewsButton.setOnClickListener { enable() }
|
||||
builder.setView(binding.root)
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
title(R.string.dialog_link_preview_title)
|
||||
text(R.string.dialog_link_preview_explanation)
|
||||
button(R.string.dialog_link_preview_enable_button_title) { enable() }
|
||||
cancelButton { dismiss() }
|
||||
}
|
||||
|
||||
private fun enable() {
|
||||
@ -22,4 +23,4 @@ class LinkPreviewDialog(private val onEnabled: () -> Unit) : BaseDialog() {
|
||||
dismiss()
|
||||
onEnabled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,23 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import network.loki.messenger.databinding.DialogSendSeedBinding
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
|
||||
/** Shown if the user is about to send their recovery phrase to someone. */
|
||||
class SendSeedDialog(private val proceed: (() -> Unit)? = null) : BaseDialog() {
|
||||
class SendSeedDialog(private val proceed: (() -> Unit)? = null) : DialogFragment() {
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
val binding = DialogSendSeedBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
binding.cancelButton.setOnClickListener { dismiss() }
|
||||
binding.sendSeedButton.setOnClickListener { send() }
|
||||
builder.setView(binding.root)
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
title(R.string.dialog_send_seed_title)
|
||||
text(R.string.dialog_send_seed_explanation)
|
||||
button(R.string.dialog_send_seed_send_button_title) { send() }
|
||||
cancelButton()
|
||||
}
|
||||
|
||||
private fun send() {
|
||||
proceed?.invoke()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.conversation.v2.menus
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.PorterDuff
|
||||
@ -15,7 +14,6 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import androidx.appcompat.widget.SearchView
|
||||
@ -34,7 +32,6 @@ import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.utilities.guava.Optional
|
||||
import org.session.libsignal.utilities.toHexString
|
||||
import org.thoughtcrime.securesms.MediaOverviewActivity
|
||||
import org.thoughtcrime.securesms.MuteDialog
|
||||
import org.thoughtcrime.securesms.ShortcutLauncherActivity
|
||||
import org.thoughtcrime.securesms.calls.WebRtcCallActivity
|
||||
import org.thoughtcrime.securesms.contacts.SelectContactsActivity
|
||||
@ -45,6 +42,8 @@ import org.thoughtcrime.securesms.groups.EditClosedGroupActivity
|
||||
import org.thoughtcrime.securesms.groups.EditClosedGroupActivity.Companion.groupIDKey
|
||||
import org.thoughtcrime.securesms.preferences.PrivacySettingsActivity
|
||||
import org.thoughtcrime.securesms.service.WebRtcCallService
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.showMuteDialog
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil
|
||||
import java.io.IOException
|
||||
|
||||
@ -186,29 +185,23 @@ object ConversationMenuHelper {
|
||||
private fun call(context: Context, thread: Recipient) {
|
||||
|
||||
if (!TextSecurePreferences.isCallNotificationsEnabled(context)) {
|
||||
val dialog = AlertDialog.Builder(context)
|
||||
.setTitle(R.string.ConversationActivity_call_title)
|
||||
.setMessage(R.string.ConversationActivity_call_prompt)
|
||||
.setPositiveButton(R.string.activity_settings_title) { _, _ ->
|
||||
val intent = Intent(context, PrivacySettingsActivity::class.java)
|
||||
context.startActivity(intent)
|
||||
context.showSessionDialog {
|
||||
title(R.string.ConversationActivity_call_title)
|
||||
text(R.string.ConversationActivity_call_prompt)
|
||||
button(R.string.activity_settings_title, R.string.AccessibilityId_settings) {
|
||||
Intent(context, PrivacySettingsActivity::class.java).let(context::startActivity)
|
||||
}
|
||||
.setNeutralButton(R.string.cancel) { d, _ ->
|
||||
d.dismiss()
|
||||
}.create()
|
||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE)?.contentDescription = context.getString(R.string.AccessibilityId_settings)
|
||||
dialog.getButton(DialogInterface.BUTTON_NEGATIVE)?.contentDescription = context.getString(R.string.AccessibilityId_cancel_button)
|
||||
dialog.show()
|
||||
cancelButton()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val service = WebRtcCallService.createCall(context, thread)
|
||||
context.startService(service)
|
||||
WebRtcCallService.createCall(context, thread)
|
||||
.let(context::startService)
|
||||
|
||||
val activity = Intent(context, WebRtcCallActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
context.startActivity(activity)
|
||||
Intent(context, WebRtcCallActivity::class.java)
|
||||
.apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK }
|
||||
.let(context::startActivity)
|
||||
|
||||
}
|
||||
|
||||
@ -295,9 +288,7 @@ object ConversationMenuHelper {
|
||||
|
||||
private fun leaveClosedGroup(context: Context, thread: Recipient) {
|
||||
if (!thread.isClosedGroupRecipient) { return }
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setTitle(context.resources.getString(R.string.ConversationActivity_leave_group))
|
||||
builder.setCancelable(true)
|
||||
|
||||
val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull()
|
||||
val admins = group.admins
|
||||
val sessionID = TextSecurePreferences.getLocalNumber(context)
|
||||
@ -307,29 +298,25 @@ object ConversationMenuHelper {
|
||||
} else {
|
||||
context.resources.getString(R.string.ConversationActivity_are_you_sure_you_want_to_leave_this_group)
|
||||
}
|
||||
builder.setMessage(message)
|
||||
builder.setPositiveButton(R.string.yes) { _, _ ->
|
||||
var groupPublicKey: String?
|
||||
var isClosedGroup: Boolean
|
||||
try {
|
||||
groupPublicKey = doubleDecodeGroupID(thread.address.toString()).toHexString()
|
||||
isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey)
|
||||
} catch (e: IOException) {
|
||||
groupPublicKey = null
|
||||
isClosedGroup = false
|
||||
}
|
||||
try {
|
||||
if (isClosedGroup) {
|
||||
MessageSender.leave(groupPublicKey!!, true)
|
||||
} else {
|
||||
Toast.makeText(context, R.string.ConversationActivity_error_leaving_group, Toast.LENGTH_LONG).show()
|
||||
|
||||
fun onLeaveFailed() = Toast.makeText(context, R.string.ConversationActivity_error_leaving_group, Toast.LENGTH_LONG).show()
|
||||
|
||||
context.showSessionDialog {
|
||||
title(R.string.ConversationActivity_leave_group)
|
||||
text(message)
|
||||
button(R.string.yes) {
|
||||
try {
|
||||
val groupPublicKey = doubleDecodeGroupID(thread.address.toString()).toHexString()
|
||||
val isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey)
|
||||
|
||||
if (isClosedGroup) MessageSender.leave(groupPublicKey, true)
|
||||
else onLeaveFailed()
|
||||
} catch (e: Exception) {
|
||||
onLeaveFailed()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(context, R.string.ConversationActivity_error_leaving_group, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
button(R.string.no)
|
||||
}
|
||||
builder.setNegativeButton(R.string.no, null)
|
||||
builder.show()
|
||||
}
|
||||
|
||||
private fun inviteContacts(context: Context, thread: Recipient) {
|
||||
@ -344,7 +331,7 @@ object ConversationMenuHelper {
|
||||
}
|
||||
|
||||
private fun mute(context: Context, thread: Recipient) {
|
||||
MuteDialog.show(ContextThemeWrapper(context, context.theme)) { until: Long ->
|
||||
showMuteDialog(ContextThemeWrapper(context, context.theme)) { until ->
|
||||
DatabaseComponent.get(context).recipientDatabase().setMuted(thread, until)
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.utilities
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import org.thoughtcrime.securesms.util.UiModeUtilities
|
||||
|
||||
open class BaseDialog : DialogFragment() {
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(requireContext())
|
||||
setContentView(builder)
|
||||
val result = builder.create()
|
||||
result.window?.setDimAmount(0.6f)
|
||||
return result
|
||||
}
|
||||
|
||||
open fun setContentView(builder: AlertDialog.Builder) {
|
||||
// To be overridden by subclasses
|
||||
}
|
||||
}
|
@ -1,21 +1,18 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.utilities
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
|
||||
object NotificationUtils {
|
||||
fun showNotifyDialog(context: Context, thread: Recipient, notifyTypeHandler: (Int)->Unit) {
|
||||
val notifyTypes = context.resources.getStringArray(R.array.notify_types)
|
||||
val currentSelected = thread.notifyType
|
||||
|
||||
AlertDialog.Builder(context)
|
||||
.setSingleChoiceItems(notifyTypes,currentSelected) { d, newSelection ->
|
||||
notifyTypeHandler(newSelection)
|
||||
d.dismiss()
|
||||
}
|
||||
.setTitle(R.string.RecipientPreferenceActivity_notification_settings)
|
||||
.show()
|
||||
context.showSessionDialog {
|
||||
title(R.string.RecipientPreferenceActivity_notification_settings)
|
||||
singleChoiceItems(
|
||||
context.resources.getStringArray(R.array.notify_types),
|
||||
thread.notifyType
|
||||
) { notifyTypeHandler(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import android.os.Bundle
|
||||
import android.text.SpannableString
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@ -41,7 +40,6 @@ import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.ThreadUtils
|
||||
import org.session.libsignal.utilities.toHexString
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.MuteDialog
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.conversation.start.NewConversationFragment
|
||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
||||
@ -63,6 +61,8 @@ import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.onboarding.SeedActivity
|
||||
import org.thoughtcrime.securesms.onboarding.SeedReminderViewDelegate
|
||||
import org.thoughtcrime.securesms.preferences.SettingsActivity
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.showMuteDialog
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.thoughtcrime.securesms.util.IP2Country
|
||||
@ -488,39 +488,39 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
||||
}
|
||||
|
||||
private fun blockConversation(thread: ThreadRecord) {
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(R.string.RecipientPreferenceActivity_block_this_contact_question)
|
||||
.setMessage(R.string.RecipientPreferenceActivity_you_will_no_longer_receive_messages_and_calls_from_this_contact)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.RecipientPreferenceActivity_block) { dialog, _ ->
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
recipientDatabase.setBlocked(thread.recipient, true)
|
||||
// TODO: Remove in UserConfig branch
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@HomeActivity)
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.recyclerView.adapter!!.notifyDataSetChanged()
|
||||
dialog.dismiss()
|
||||
}
|
||||
showSessionDialog {
|
||||
title(R.string.RecipientPreferenceActivity_block_this_contact_question)
|
||||
text(R.string.RecipientPreferenceActivity_you_will_no_longer_receive_messages_and_calls_from_this_contact)
|
||||
button(R.string.RecipientPreferenceActivity_block) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
recipientDatabase.setBlocked(thread.recipient, true)
|
||||
// TODO: Remove in UserConfig branch
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@HomeActivity)
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.recyclerView.adapter!!.notifyDataSetChanged()
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
|
||||
private fun unblockConversation(thread: ThreadRecord) {
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(R.string.RecipientPreferenceActivity_unblock_this_contact_question)
|
||||
.setMessage(R.string.RecipientPreferenceActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.RecipientPreferenceActivity_unblock) { dialog, _ ->
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
recipientDatabase.setBlocked(thread.recipient, false)
|
||||
// TODO: Remove in UserConfig branch
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@HomeActivity)
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.recyclerView.adapter!!.notifyDataSetChanged()
|
||||
dialog.dismiss()
|
||||
}
|
||||
showSessionDialog {
|
||||
title(R.string.RecipientPreferenceActivity_unblock_this_contact_question)
|
||||
text(R.string.RecipientPreferenceActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact)
|
||||
button(R.string.RecipientPreferenceActivity_unblock) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
recipientDatabase.setBlocked(thread.recipient, false)
|
||||
// TODO: Remove in UserConfig branch
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@HomeActivity)
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.recyclerView.adapter!!.notifyDataSetChanged()
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setConversationMuted(thread: ThreadRecord, isMuted: Boolean) {
|
||||
@ -532,7 +532,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MuteDialog.show(this) { until: Long ->
|
||||
showMuteDialog(this) { until ->
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
recipientDatabase.setMuted(thread.recipient, until)
|
||||
withContext(Dispatchers.Main) {
|
||||
@ -578,48 +578,41 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
||||
} else {
|
||||
resources.getString(R.string.activity_home_delete_conversation_dialog_message)
|
||||
}
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
dialog.setMessage(message)
|
||||
dialog.setPositiveButton(R.string.yes) { _, _ ->
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
val context = this@HomeActivity as Context
|
||||
// Cancel any outstanding jobs
|
||||
DatabaseComponent.get(context).sessionJobDatabase().cancelPendingMessageSendJobs(threadID)
|
||||
// Send a leave group message if this is an active closed group
|
||||
if (recipient.address.isClosedGroup && DatabaseComponent.get(context).groupDatabase().isActive(recipient.address.toGroupString())) {
|
||||
var isClosedGroup: Boolean
|
||||
var groupPublicKey: String?
|
||||
try {
|
||||
groupPublicKey = GroupUtil.doubleDecodeGroupID(recipient.address.toString()).toHexString()
|
||||
isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey)
|
||||
} catch (e: IOException) {
|
||||
groupPublicKey = null
|
||||
isClosedGroup = false
|
||||
|
||||
showSessionDialog {
|
||||
text(message)
|
||||
button(R.string.yes) {
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
val context = this@HomeActivity
|
||||
// Cancel any outstanding jobs
|
||||
DatabaseComponent.get(context).sessionJobDatabase().cancelPendingMessageSendJobs(threadID)
|
||||
// Send a leave group message if this is an active closed group
|
||||
if (recipient.address.isClosedGroup && DatabaseComponent.get(context).groupDatabase().isActive(recipient.address.toGroupString())) {
|
||||
try {
|
||||
GroupUtil.doubleDecodeGroupID(recipient.address.toString()).toHexString()
|
||||
.takeIf(DatabaseComponent.get(context).lokiAPIDatabase()::isClosedGroup)
|
||||
?.let { MessageSender.explicitLeave(it, false) }
|
||||
} catch (_: IOException) {
|
||||
}
|
||||
}
|
||||
if (isClosedGroup) {
|
||||
MessageSender.explicitLeave(groupPublicKey!!, false)
|
||||
// Delete the conversation
|
||||
val v2OpenGroup = DatabaseComponent.get(context).lokiThreadDatabase().getOpenGroupChat(threadID)
|
||||
if (v2OpenGroup != null) {
|
||||
v2OpenGroup.apply { OpenGroupManager.delete(server, room, context) }
|
||||
} else {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
threadDb.deleteConversation(threadID)
|
||||
}
|
||||
}
|
||||
// Update the badge count
|
||||
ApplicationContext.getInstance(context).messageNotifier.updateNotification(context)
|
||||
// Notify the user
|
||||
val toastMessage = if (recipient.isGroupRecipient) R.string.MessageRecord_left_group else R.string.activity_home_conversation_deleted_message
|
||||
Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
// Delete the conversation
|
||||
val v2OpenGroup = DatabaseComponent.get(this@HomeActivity).lokiThreadDatabase().getOpenGroupChat(threadID)
|
||||
if (v2OpenGroup != null) {
|
||||
OpenGroupManager.delete(v2OpenGroup.server, v2OpenGroup.room, this@HomeActivity)
|
||||
} else {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
threadDb.deleteConversation(threadID)
|
||||
}
|
||||
}
|
||||
// Update the badge count
|
||||
ApplicationContext.getInstance(context).messageNotifier.updateNotification(context)
|
||||
// Notify the user
|
||||
val toastMessage = if (recipient.isGroupRecipient) R.string.MessageRecord_left_group else R.string.activity_home_conversation_deleted_message
|
||||
Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
button(R.string.no)
|
||||
}
|
||||
dialog.setNegativeButton(R.string.no) { _, _ ->
|
||||
// Do nothing
|
||||
}
|
||||
dialog.create().show()
|
||||
}
|
||||
|
||||
private fun openSettings() {
|
||||
@ -633,17 +626,15 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
||||
}
|
||||
|
||||
private fun hideMessageRequests() {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage("Hide message requests?")
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
showSessionDialog {
|
||||
text("Hide message requests?")
|
||||
button(R.string.yes) {
|
||||
textSecurePreferences.setHasHiddenMessageRequests()
|
||||
setupMessageRequestsBanner()
|
||||
homeViewModel.tryUpdateChannel()
|
||||
}
|
||||
.setNegativeButton(R.string.no) { _, _ ->
|
||||
// Do nothing
|
||||
}
|
||||
.create().show()
|
||||
button(R.string.no)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showNewConversation() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.thoughtcrime.securesms.messagerequests
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
@ -20,6 +19,7 @@ import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
import org.thoughtcrime.securesms.util.push
|
||||
import javax.inject.Inject
|
||||
@ -77,34 +77,34 @@ class MessageRequestsActivity : PassphraseRequiredActionBarActivity(), Conversat
|
||||
}
|
||||
|
||||
override fun onBlockConversationClick(thread: ThreadRecord) {
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
dialog.setTitle(R.string.RecipientPreferenceActivity_block_this_contact_question)
|
||||
.setMessage(R.string.message_requests_block_message)
|
||||
.setPositiveButton(R.string.recipient_preferences__block) { _, _ ->
|
||||
viewModel.blockMessageRequest(thread)
|
||||
LoaderManager.getInstance(this).restartLoader(0, null, this)
|
||||
}
|
||||
.setNegativeButton(R.string.no) { _, _ ->
|
||||
// Do nothing
|
||||
}
|
||||
dialog.create().show()
|
||||
fun doBlock() {
|
||||
viewModel.blockMessageRequest(thread)
|
||||
LoaderManager.getInstance(this).restartLoader(0, null, this)
|
||||
}
|
||||
|
||||
showSessionDialog {
|
||||
title(R.string.RecipientPreferenceActivity_block_this_contact_question)
|
||||
text(R.string.message_requests_block_message)
|
||||
button(R.string.recipient_preferences__block) { doBlock() }
|
||||
button(R.string.no)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDeleteConversationClick(thread: ThreadRecord) {
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
dialog.setTitle(R.string.decline)
|
||||
.setMessage(resources.getString(R.string.message_requests_decline_message))
|
||||
.setPositiveButton(R.string.decline) { _,_ ->
|
||||
viewModel.deleteMessageRequest(thread)
|
||||
LoaderManager.getInstance(this).restartLoader(0, null, this)
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@MessageRequestsActivity)
|
||||
}
|
||||
fun doDecline() {
|
||||
viewModel.deleteMessageRequest(thread)
|
||||
LoaderManager.getInstance(this).restartLoader(0, null, this)
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@MessageRequestsActivity)
|
||||
}
|
||||
.setNegativeButton(R.string.no) { _, _ ->
|
||||
// Do nothing
|
||||
}
|
||||
dialog.create().show()
|
||||
}
|
||||
|
||||
showSessionDialog {
|
||||
title(R.string.decline)
|
||||
text(resources.getString(R.string.message_requests_decline_message))
|
||||
button(R.string.decline) { doDecline() }
|
||||
button(R.string.no)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateEmptyState() {
|
||||
@ -114,18 +114,18 @@ class MessageRequestsActivity : PassphraseRequiredActionBarActivity(), Conversat
|
||||
}
|
||||
|
||||
private fun deleteAllAndBlock() {
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
dialog.setMessage(resources.getString(R.string.message_requests_clear_all_message))
|
||||
dialog.setPositiveButton(R.string.yes) { _, _ ->
|
||||
fun doDeleteAllAndBlock() {
|
||||
viewModel.clearAllMessageRequests()
|
||||
LoaderManager.getInstance(this).restartLoader(0, null, this)
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@MessageRequestsActivity)
|
||||
}
|
||||
}
|
||||
dialog.setNegativeButton(R.string.no) { _, _ ->
|
||||
// Do nothing
|
||||
|
||||
showSessionDialog {
|
||||
text(resources.getString(R.string.message_requests_clear_all_message))
|
||||
button(R.string.yes) { doDeleteAllAndBlock() }
|
||||
button(R.string.no)
|
||||
}
|
||||
dialog.create().show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.onboarding
|
||||
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.TransitionDrawable
|
||||
import android.net.Uri
|
||||
@ -20,6 +19,7 @@ import org.session.libsession.utilities.ThemeUtil
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.home.HomeActivity
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.util.GlowViewUtilities
|
||||
import org.thoughtcrime.securesms.util.PNModeView
|
||||
import org.thoughtcrime.securesms.util.disableClipping
|
||||
@ -151,12 +151,13 @@ class PNModeActivity : BaseActionBarActivity() {
|
||||
|
||||
private fun register() {
|
||||
if (selectedOptionView == null) {
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
dialog.setTitle(R.string.activity_pn_mode_no_option_picked_dialog_title)
|
||||
dialog.setPositiveButton(R.string.ok) { _, _ -> }
|
||||
dialog.create().show()
|
||||
showSessionDialog {
|
||||
title(R.string.activity_pn_mode_no_option_picked_dialog_title)
|
||||
button(R.string.ok)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
TextSecurePreferences.setIsUsingFCM(this, (selectedOptionView == binding.fcmOptionView))
|
||||
val application = ApplicationContext.getInstance(this)
|
||||
application.startPollingIfNeeded()
|
||||
|
@ -162,15 +162,13 @@ public class Permissions {
|
||||
request.onResult(requestedPermissions, grantResults, new boolean[requestedPermissions.length]);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void executePermissionsRequestWithRationale(PermissionsRequest request) {
|
||||
AlertDialog dialog = RationaleDialog.createFor(permissionObject.getContext(), rationaleDialogMessage, rationalDialogHeader)
|
||||
.setPositiveButton(R.string.Permissions_continue, (d, which) -> executePermissionsRequest(request))
|
||||
.setNegativeButton(R.string.Permissions_not_now, (d, which) -> executeNoPermissionsRequest(request))
|
||||
.show();
|
||||
dialog.getWindow().setLayout((int)(permissionObject.getWindowWidth() * .75), ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
positiveButton.setContentDescription("Continue");
|
||||
RationaleDialog.show(
|
||||
permissionObject.getContext(),
|
||||
rationaleDialogMessage,
|
||||
() -> executePermissionsRequest(request),
|
||||
() -> executeNoPermissionsRequest(request),
|
||||
rationalDialogHeader);
|
||||
}
|
||||
|
||||
private void executePermissionsRequest(PermissionsRequest request) {
|
||||
@ -257,7 +255,7 @@ public class Permissions {
|
||||
resultListener.onResult(permissions, grantResults, shouldShowRationaleDialog);
|
||||
}
|
||||
|
||||
private static Intent getApplicationSettingsIntent(@NonNull Context context) {
|
||||
static Intent getApplicationSettingsIntent(@NonNull Context context) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
Uri uri = Uri.fromParts("package", context.getPackageName(), null);
|
||||
@ -354,20 +352,8 @@ public class Permissions {
|
||||
@Override
|
||||
public void run() {
|
||||
Context context = this.context.get();
|
||||
|
||||
if (context != null) {
|
||||
AlertDialog alertDialog = new AlertDialog.Builder(context, R.style.ThemeOverlay_Session_AlertDialog)
|
||||
.setTitle(R.string.Permissions_permission_required)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.Permissions_continue, (dialog, which) -> context.startActivity(getApplicationSettingsIntent(context)))
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create();
|
||||
Button positiveButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
if (positiveButton != null) {
|
||||
positiveButton.setContentDescription(context.getString(R.string.AccessibilityId_continue));
|
||||
}
|
||||
alertDialog.show();
|
||||
}
|
||||
if (context == null) return;
|
||||
SettingsDialog.show(context, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
package org.thoughtcrime.securesms.permissions;
|
||||
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.session.libsession.utilities.ViewUtil;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class RationaleDialog {
|
||||
|
||||
public static AlertDialog.Builder createFor(@NonNull Context context, @NonNull String message, @DrawableRes int... drawables) {
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.permissions_rationale_dialog, null);
|
||||
view.setClipToOutline(true);
|
||||
ViewGroup header = view.findViewById(R.id.header_container);
|
||||
TextView text = view.findViewById(R.id.message);
|
||||
|
||||
for (int i=0;i<drawables.length;i++) {
|
||||
ImageView imageView = new ImageView(context);
|
||||
imageView.setImageDrawable(context.getResources().getDrawable(drawables[i]));
|
||||
imageView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
||||
|
||||
header.addView(imageView);
|
||||
|
||||
if (i != drawables.length - 1) {
|
||||
TextView plus = new TextView(context);
|
||||
plus.setText("+");
|
||||
plus.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40);
|
||||
plus.setTextColor(Color.WHITE);
|
||||
|
||||
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.setMargins(ViewUtil.dpToPx(context, 20), 0, ViewUtil.dpToPx(context, 20), 0);
|
||||
|
||||
plus.setLayoutParams(layoutParams);
|
||||
header.addView(plus);
|
||||
}
|
||||
}
|
||||
|
||||
text.setText(message);
|
||||
|
||||
return new AlertDialog.Builder(context, R.style.ThemeOverlay_Session_AlertDialog).setView(view);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package org.thoughtcrime.securesms.permissions
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.ViewUtil
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
|
||||
object RationaleDialog {
|
||||
@JvmStatic
|
||||
fun show(
|
||||
context: Context,
|
||||
message: String,
|
||||
onPositive: Runnable,
|
||||
onNegative: Runnable,
|
||||
@DrawableRes vararg drawables: Int
|
||||
): AlertDialog {
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.permissions_rationale_dialog, null)
|
||||
.apply { clipToOutline = true }
|
||||
val header = view.findViewById<ViewGroup>(R.id.header_container)
|
||||
view.findViewById<TextView>(R.id.message).text = message
|
||||
|
||||
fun addIcon(id: Int) {
|
||||
ImageView(context).apply {
|
||||
setImageDrawable(ResourcesCompat.getDrawable(context.resources, id, context.theme))
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
|
||||
}.also(header::addView)
|
||||
}
|
||||
|
||||
fun addPlus() {
|
||||
TextView(context).apply {
|
||||
text = "+"
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_SP, 40f)
|
||||
setTextColor(Color.WHITE)
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||
ViewUtil.dpToPx(context, 20).let { setMargins(it, 0, it, 0) }
|
||||
}
|
||||
}.also(header::addView)
|
||||
}
|
||||
|
||||
drawables.firstOrNull()?.let(::addIcon)
|
||||
drawables.drop(1).forEach { addPlus(); addIcon(it) }
|
||||
|
||||
return context.showSessionDialog {
|
||||
view(view)
|
||||
button(R.string.Permissions_continue) { onPositive.run() }
|
||||
button(R.string.Permissions_not_now) { onNegative.run() }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package org.thoughtcrime.securesms.permissions
|
||||
|
||||
import android.content.Context
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
|
||||
class SettingsDialog {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(context: Context, message: String) {
|
||||
context.showSessionDialog {
|
||||
title(R.string.Permissions_permission_required)
|
||||
text(message)
|
||||
button(R.string.Permissions_continue, R.string.AccessibilityId_continue) {
|
||||
context.startActivity(Permissions.getApplicationSettingsIntent(context))
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.view.isVisible
|
||||
@ -8,6 +7,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.ActivityBlockedContactsBinding
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
|
||||
@AndroidEntryPoint
|
||||
class BlockedContactsActivity: PassphraseRequiredActionBarActivity() {
|
||||
@ -19,17 +19,12 @@ class BlockedContactsActivity: PassphraseRequiredActionBarActivity() {
|
||||
val adapter: BlockedContactsAdapter by lazy { BlockedContactsAdapter(viewModel) }
|
||||
|
||||
fun unblock() {
|
||||
// show dialog
|
||||
val title = viewModel.getTitle(this)
|
||||
|
||||
val message = viewModel.getMessage(this)
|
||||
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.continue_2) { _, _ -> viewModel.unblock(this@BlockedContactsActivity) }
|
||||
.setNegativeButton(R.string.cancel) { _, _ -> }
|
||||
.show()
|
||||
showSessionDialog {
|
||||
title(viewModel.getTitle(this@BlockedContactsActivity))
|
||||
text(viewModel.getMessage(this@BlockedContactsActivity))
|
||||
button(R.string.continue_2) { viewModel.unblock(this@BlockedContactsActivity) }
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
@ -51,4 +46,3 @@ class BlockedContactsActivity: PassphraseRequiredActionBarActivity() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.Manifest
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.preference.Preference
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.setBooleanPreference
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
|
||||
internal class CallToggleListener(
|
||||
private val context: Fragment,
|
||||
private val setCallback: (Boolean) -> Unit
|
||||
) : Preference.OnPreferenceChangeListener {
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
if (newValue == false) return true
|
||||
|
||||
// check if we've shown the info dialog and check for microphone permissions
|
||||
context.showSessionDialog {
|
||||
title(R.string.dialog_voice_video_title)
|
||||
text(R.string.dialog_voice_video_message)
|
||||
button(R.string.dialog_link_preview_enable_button_title, R.string.AccessibilityId_enable) { requestMicrophonePermission() }
|
||||
cancelButton()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun requestMicrophonePermission() {
|
||||
Permissions.with(context)
|
||||
.request(Manifest.permission.RECORD_AUDIO)
|
||||
.onAllGranted {
|
||||
setBooleanPreference(
|
||||
context.requireContext(),
|
||||
TextSecurePreferences.CALL_NOTIFICATIONS_ENABLED,
|
||||
true
|
||||
)
|
||||
setCallback(true)
|
||||
}
|
||||
.onAnyDenied { setCallback(false) }
|
||||
.execute()
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.DialogFragment
|
||||
|
||||
class ChangeUiModeDialog : DialogFragment() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "ChangeUiModeDialog"
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val context = requireContext()
|
||||
return android.app.AlertDialog.Builder(context)
|
||||
.setTitle("TODO: remove this")
|
||||
.show()
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import android.view.View
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -15,10 +18,10 @@ import network.loki.messenger.databinding.DialogClearAllDataBinding
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
|
||||
class ClearAllDataDialog : BaseDialog() {
|
||||
class ClearAllDataDialog : DialogFragment() {
|
||||
private lateinit var binding: DialogClearAllDataBinding
|
||||
|
||||
enum class Steps {
|
||||
@ -35,7 +38,11 @@ class ClearAllDataDialog : BaseDialog() {
|
||||
updateUI()
|
||||
}
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
view(createView())
|
||||
}
|
||||
|
||||
private fun createView(): View {
|
||||
binding = DialogClearAllDataBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
val device = RadioOption("deviceOnly", requireContext().getString(R.string.dialog_clear_all_data_clear_device_only))
|
||||
val network = RadioOption("deviceAndNetwork", requireContext().getString(R.string.dialog_clear_all_data_clear_device_and_network))
|
||||
@ -62,8 +69,7 @@ class ClearAllDataDialog : BaseDialog() {
|
||||
Steps.DELETING -> { /* do nothing intentionally */ }
|
||||
}
|
||||
}
|
||||
builder.setView(binding.root)
|
||||
builder.setCancelable(false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private fun updateUI() {
|
||||
|
@ -1,41 +1,24 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.preference.ListPreference
|
||||
import network.loki.messenger.databinding.DialogListPreferenceBinding
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
|
||||
fun listPreferenceDialog(
|
||||
context: Context,
|
||||
listPreference: ListPreference,
|
||||
dialogListener: () -> Unit
|
||||
) : AlertDialog {
|
||||
onChange: () -> Unit
|
||||
) : AlertDialog = listPreference.run {
|
||||
context.showSessionDialog {
|
||||
val index = entryValues.indexOf(value)
|
||||
val options = entries.map(CharSequence::toString).toTypedArray()
|
||||
|
||||
val builder = AlertDialog.Builder(context)
|
||||
|
||||
val binding = DialogListPreferenceBinding.inflate(LayoutInflater.from(context))
|
||||
binding.titleTextView.text = listPreference.dialogTitle
|
||||
binding.messageTextView.text = listPreference.dialogMessage
|
||||
|
||||
builder.setView(binding.root)
|
||||
|
||||
val dialog = builder.show()
|
||||
|
||||
val valueIndex = listPreference.findIndexOfValue(listPreference.value)
|
||||
RadioOptionAdapter(valueIndex) {
|
||||
listPreference.value = it.value
|
||||
dialog.dismiss()
|
||||
dialogListener()
|
||||
}
|
||||
.apply {
|
||||
listPreference.entryValues.zip(listPreference.entries) { value, title ->
|
||||
RadioOption(value.toString(), title.toString())
|
||||
}.let(this::submitList)
|
||||
title(dialogTitle)
|
||||
text(dialogMessage)
|
||||
singleChoiceItems(options, index) {
|
||||
listPreference.setValueIndex(it)
|
||||
onChange()
|
||||
}
|
||||
.let { binding.recyclerView.adapter = it }
|
||||
|
||||
binding.closeButton.setOnClickListener { dialog.dismiss() }
|
||||
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
|
@ -1,203 +0,0 @@
|
||||
package org.thoughtcrime.securesms.preferences;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.widget.Button;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.components.SwitchPreferenceCompat;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.util.CallNotificationBuilder;
|
||||
import org.thoughtcrime.securesms.util.IntentUtils;
|
||||
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import network.loki.messenger.BuildConfig;
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class PrivacySettingsPreferenceFragment extends ListSummaryPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle paramBundle) {
|
||||
super.onCreate(paramBundle);
|
||||
|
||||
this.findPreference(TextSecurePreferences.SCREEN_LOCK).setOnPreferenceChangeListener(new ScreenLockListener());
|
||||
|
||||
this.findPreference(TextSecurePreferences.READ_RECEIPTS_PREF).setOnPreferenceChangeListener(new ReadReceiptToggleListener());
|
||||
this.findPreference(TextSecurePreferences.TYPING_INDICATORS).setOnPreferenceChangeListener(new TypingIndicatorsToggleListener());
|
||||
this.findPreference(TextSecurePreferences.LINK_PREVIEWS).setOnPreferenceChangeListener(new LinkPreviewToggleListener());
|
||||
this.findPreference(TextSecurePreferences.CALL_NOTIFICATIONS_ENABLED).setOnPreferenceChangeListener(new CallToggleListener(this, this::setCall));
|
||||
|
||||
initializeVisibility();
|
||||
}
|
||||
|
||||
private Void setCall(boolean isEnabled) {
|
||||
((SwitchPreferenceCompat)findPreference(TextSecurePreferences.CALL_NOTIFICATIONS_ENABLED)).setChecked(isEnabled);
|
||||
if (isEnabled && !CallNotificationBuilder.areNotificationsEnabled(requireActivity())) {
|
||||
// show a dialog saying that calls won't work properly if you don't have notifications on at a system level
|
||||
new AlertDialog.Builder(new ContextThemeWrapper(requireActivity(), R.style.ThemeOverlay_Session_AlertDialog))
|
||||
.setTitle(R.string.CallNotificationBuilder_system_notification_title)
|
||||
.setMessage(R.string.CallNotificationBuilder_system_notification_message)
|
||||
.setPositiveButton(R.string.activity_notification_settings_title, (d, w) -> {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
Intent settingsIntent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID);
|
||||
if (IntentUtils.isResolvable(requireContext(), settingsIntent)) {
|
||||
startActivity(settingsIntent);
|
||||
}
|
||||
} else {
|
||||
Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.setData(Uri.parse("package:"+BuildConfig.APPLICATION_ID));
|
||||
if (IntentUtils.isResolvable(requireContext(), settingsIntent)) {
|
||||
startActivity(settingsIntent);
|
||||
}
|
||||
}
|
||||
d.dismiss();
|
||||
})
|
||||
.setNeutralButton(R.string.dismiss, (d, w) -> {
|
||||
// do nothing, user might have broken notifications
|
||||
d.dismiss();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.preferences_app_protection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
private void initializeVisibility() {
|
||||
if (TextSecurePreferences.isPasswordDisabled(getContext())) {
|
||||
KeyguardManager keyguardManager = (KeyguardManager)getContext().getSystemService(Context.KEYGUARD_SERVICE);
|
||||
if (!keyguardManager.isKeyguardSecure()) {
|
||||
((SwitchPreferenceCompat)findPreference(TextSecurePreferences.SCREEN_LOCK)).setChecked(false);
|
||||
findPreference(TextSecurePreferences.SCREEN_LOCK).setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
findPreference(TextSecurePreferences.SCREEN_LOCK).setVisible(false);
|
||||
findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private class ScreenLockListener implements Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean enabled = (Boolean)newValue;
|
||||
|
||||
TextSecurePreferences.setScreenLockEnabled(getContext(), enabled);
|
||||
|
||||
Intent intent = new Intent(getContext(), KeyCachingService.class);
|
||||
intent.setAction(KeyCachingService.LOCK_TOGGLED_EVENT);
|
||||
getContext().startService(intent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class ReadReceiptToggleListener implements Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class TypingIndicatorsToggleListener implements Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean enabled = (boolean)newValue;
|
||||
|
||||
if (!enabled) {
|
||||
ApplicationContext.getInstance(requireContext()).getTypingStatusRepository().clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class LinkPreviewToggleListener implements Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class CallToggleListener implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private final Fragment context;
|
||||
private final Function1<Boolean, Void> setCallback;
|
||||
|
||||
private CallToggleListener(Fragment context, Function1<Boolean,Void> setCallback) {
|
||||
this.context = context;
|
||||
this.setCallback = setCallback;
|
||||
}
|
||||
|
||||
private void requestMicrophonePermission() {
|
||||
Permissions.with(context)
|
||||
.request(Manifest.permission.RECORD_AUDIO)
|
||||
.onAllGranted(() -> {
|
||||
TextSecurePreferences.setBooleanPreference(context.requireContext(), TextSecurePreferences.CALL_NOTIFICATIONS_ENABLED, true);
|
||||
setCallback.invoke(true);
|
||||
})
|
||||
.onAnyDenied(() -> setCallback.invoke(false))
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean val = (boolean) newValue;
|
||||
if (val) {
|
||||
// check if we've shown the info dialog and check for microphone permissions
|
||||
AlertDialog dialog = new AlertDialog.Builder(new ContextThemeWrapper(context.requireContext(), R.style.ThemeOverlay_Session_AlertDialog))
|
||||
.setTitle(R.string.dialog_voice_video_title)
|
||||
.setMessage(R.string.dialog_voice_video_message)
|
||||
.setPositiveButton(R.string.dialog_link_preview_enable_button_title, (d, w) -> {
|
||||
requestMicrophonePermission();
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, (d, w) -> {
|
||||
|
||||
})
|
||||
.show();
|
||||
Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
positiveButton.setContentDescription("Enable");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import androidx.preference.Preference
|
||||
import network.loki.messenger.BuildConfig
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.isPasswordDisabled
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.setScreenLockEnabled
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.components.SwitchPreferenceCompat
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.areNotificationsEnabled
|
||||
import org.thoughtcrime.securesms.util.IntentUtils
|
||||
|
||||
class PrivacySettingsPreferenceFragment : ListSummaryPreferenceFragment() {
|
||||
override fun onCreate(paramBundle: Bundle?) {
|
||||
super.onCreate(paramBundle)
|
||||
findPreference<Preference>(TextSecurePreferences.SCREEN_LOCK)!!
|
||||
.onPreferenceChangeListener = ScreenLockListener()
|
||||
findPreference<Preference>(TextSecurePreferences.TYPING_INDICATORS)!!
|
||||
.onPreferenceChangeListener = TypingIndicatorsToggleListener()
|
||||
findPreference<Preference>(TextSecurePreferences.CALL_NOTIFICATIONS_ENABLED)!!
|
||||
.onPreferenceChangeListener = CallToggleListener(this) { setCall(it) }
|
||||
initializeVisibility()
|
||||
}
|
||||
|
||||
private fun setCall(isEnabled: Boolean) {
|
||||
(findPreference<Preference>(TextSecurePreferences.CALL_NOTIFICATIONS_ENABLED) as SwitchPreferenceCompat?)!!.isChecked =
|
||||
isEnabled
|
||||
if (isEnabled && !areNotificationsEnabled(requireActivity())) {
|
||||
// show a dialog saying that calls won't work properly if you don't have notifications on at a system level
|
||||
showSessionDialog {
|
||||
title(R.string.CallNotificationBuilder_system_notification_title)
|
||||
text(R.string.CallNotificationBuilder_system_notification_message)
|
||||
button(R.string.activity_notification_settings_title) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||
.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID)
|
||||
} else {
|
||||
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
.setData(Uri.parse("package:" + BuildConfig.APPLICATION_ID))
|
||||
}
|
||||
.apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
|
||||
.takeIf { IntentUtils.isResolvable(requireContext(), it) }.let {
|
||||
startActivity(it)
|
||||
}
|
||||
}
|
||||
button(R.string.dismiss)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.preferences_app_protection)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
private fun initializeVisibility() {
|
||||
if (isPasswordDisabled(requireContext())) {
|
||||
val keyguardManager =
|
||||
requireContext().getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
||||
if (!keyguardManager.isKeyguardSecure) {
|
||||
findPreference<SwitchPreferenceCompat>(TextSecurePreferences.SCREEN_LOCK)!!.isChecked = false
|
||||
findPreference<Preference>(TextSecurePreferences.SCREEN_LOCK)!!.isEnabled = false
|
||||
}
|
||||
} else {
|
||||
findPreference<Preference>(TextSecurePreferences.SCREEN_LOCK)!!.isVisible = false
|
||||
findPreference<Preference>(TextSecurePreferences.SCREEN_LOCK_TIMEOUT)!!.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
private inner class ScreenLockListener : Preference.OnPreferenceChangeListener {
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
val enabled = newValue as Boolean
|
||||
setScreenLockEnabled(context!!, enabled)
|
||||
val intent = Intent(context, KeyCachingService::class.java)
|
||||
intent.action = KeyCachingService.LOCK_TOGGLED_EVENT
|
||||
context!!.startService(intent)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private inner class TypingIndicatorsToggleListener : Preference.OnPreferenceChangeListener {
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
val enabled = newValue as Boolean
|
||||
if (!enabled) {
|
||||
ApplicationContext.getInstance(requireContext()).typingStatusRepository.clear()
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +1,34 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.DialogSeedBinding
|
||||
import org.session.libsignal.crypto.MnemonicCodec
|
||||
import org.session.libsignal.utilities.hexEncodedPrivateKey
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
|
||||
class SeedDialog : BaseDialog() {
|
||||
|
||||
class SeedDialog: DialogFragment() {
|
||||
private val seed by lazy {
|
||||
var hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED)
|
||||
if (hexEncodedSeed == null) {
|
||||
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(requireContext()).hexEncodedPrivateKey // Legacy account
|
||||
}
|
||||
val loadFileContents: (String) -> String = { fileName ->
|
||||
MnemonicUtilities.loadFileContents(requireContext(), fileName)
|
||||
}
|
||||
MnemonicCodec(loadFileContents).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english)
|
||||
val hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED)
|
||||
?: IdentityKeyUtil.getIdentityKeyPair(requireContext()).hexEncodedPrivateKey // Legacy account
|
||||
|
||||
MnemonicCodec { fileName -> MnemonicUtilities.loadFileContents(requireContext(), fileName) }
|
||||
.encode(hexEncodedSeed, MnemonicCodec.Language.Configuration.english)
|
||||
}
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
val binding = DialogSeedBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
binding.seedTextView.text = seed
|
||||
binding.closeButton.setOnClickListener { dismiss() }
|
||||
binding.copyButton.setOnClickListener { copySeed() }
|
||||
builder.setView(binding.root)
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
title(R.string.dialog_seed_title)
|
||||
text(R.string.dialog_seed_explanation)
|
||||
text(seed, R.style.SessionIDTextView)
|
||||
button(R.string.copy, R.string.AccessibilityId_copy_recovery_phrase) { copySeed() }
|
||||
button(R.string.close) { dismiss() }
|
||||
}
|
||||
|
||||
private fun copySeed() {
|
||||
@ -42,4 +38,4 @@ class SeedDialog : BaseDialog() {
|
||||
Toast.makeText(requireContext(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import network.loki.messenger.BuildConfig
|
||||
import network.loki.messenger.R
|
||||
@ -40,6 +39,7 @@ import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.preferences.appearance.AppearanceSettingsActivity
|
||||
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
@ -264,19 +264,15 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
}
|
||||
|
||||
private fun showEditProfilePictureUI() {
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(R.string.activity_settings_set_display_picture)
|
||||
.setView(R.layout.dialog_change_avatar)
|
||||
.setPositiveButton(R.string.activity_settings_upload) { _, _ ->
|
||||
startAvatarSelection()
|
||||
showSessionDialog {
|
||||
title(R.string.activity_settings_set_display_picture)
|
||||
view(R.layout.dialog_change_avatar)
|
||||
button(R.string.activity_settings_upload) { startAvatarSelection() }
|
||||
if (TextSecurePreferences.getProfileAvatarId(context) != 0) {
|
||||
button(R.string.activity_settings_remove) { removeAvatar() }
|
||||
}
|
||||
.setNegativeButton(R.string.cancel) { _, _ -> }
|
||||
.apply {
|
||||
if (TextSecurePreferences.getProfileAvatarId(context) != 0) {
|
||||
setNeutralButton(R.string.activity_settings_remove) { _, _ -> removeAvatar() }
|
||||
}
|
||||
}
|
||||
.show().apply {
|
||||
cancelButton()
|
||||
}.apply {
|
||||
val profilePic = findViewById<ProfilePictureView>(R.id.profile_picture_view)
|
||||
?.also(::setupProfilePictureView)
|
||||
|
||||
|
@ -1,17 +1,18 @@
|
||||
package org.thoughtcrime.securesms.preferences
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.ContentResolver
|
||||
import android.content.ContentValues
|
||||
import android.content.Intent
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import android.view.LayoutInflater
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
@ -20,11 +21,10 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import network.loki.messenger.BuildConfig
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.DialogShareLogsBinding
|
||||
import org.session.libsignal.utilities.ExternalStorageUtil
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
import org.thoughtcrime.securesms.util.FileProviderUtil
|
||||
import org.thoughtcrime.securesms.util.StreamUtil
|
||||
import java.io.File
|
||||
@ -33,21 +33,15 @@ import java.io.IOException
|
||||
import java.util.Objects
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ShareLogsDialog : BaseDialog() {
|
||||
class ShareLogsDialog : DialogFragment() {
|
||||
|
||||
private var shareJob: Job? = null
|
||||
|
||||
override fun setContentView(builder: AlertDialog.Builder) {
|
||||
val binding = DialogShareLogsBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
binding.cancelButton.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
binding.shareButton.setOnClickListener {
|
||||
// start the export and share
|
||||
shareLogs()
|
||||
}
|
||||
builder.setView(binding.root)
|
||||
builder.setCancelable(false)
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
title(R.string.dialog_share_logs_title)
|
||||
text(R.string.dialog_share_logs_explanation)
|
||||
button(R.string.share) { shareLogs() }
|
||||
cancelButton { dismiss() }
|
||||
}
|
||||
|
||||
private fun shareLogs() {
|
||||
|
@ -7,10 +7,10 @@ import android.view.View
|
||||
import androidx.annotation.StyleRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
|
||||
fun BaseActionBarActivity.setUpActionBarSessionLogo(hideBackButton: Boolean = false) {
|
||||
val actionbar = supportActionBar!!
|
||||
@ -66,7 +66,7 @@ interface ActivityDispatcher {
|
||||
fun get(context: Context) = context.getSystemService(SERVICE) as? ActivityDispatcher
|
||||
}
|
||||
fun dispatchIntent(body: (Context)->Intent?)
|
||||
fun showDialog(baseDialog: BaseDialog, tag: String? = null)
|
||||
fun showDialog(dialogFragment: DialogFragment, tag: String? = null)
|
||||
}
|
||||
|
||||
fun TextSecurePreferences.themeState(): ThemeState {
|
||||
|
@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.util
|
||||
import android.content.ContentResolver
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface.OnClickListener
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
@ -12,12 +11,12 @@ import android.provider.MediaStore
|
||||
import android.text.TextUtils
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.task.ProgressDialogAsyncTask
|
||||
import org.session.libsignal.utilities.ExternalStorageUtil
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
@ -30,7 +29,12 @@ import java.util.concurrent.TimeUnit
|
||||
* Saves attachment files to an external storage using [MediaStore] API.
|
||||
* Requires [android.Manifest.permission.WRITE_EXTERNAL_STORAGE] on API 28 and below.
|
||||
*/
|
||||
class SaveAttachmentTask : ProgressDialogAsyncTask<SaveAttachmentTask.Attachment, Void, Pair<Int, String?>> {
|
||||
class SaveAttachmentTask @JvmOverloads constructor(context: Context, count: Int = 1) :
|
||||
ProgressDialogAsyncTask<SaveAttachmentTask.Attachment, Void, Pair<Int, String?>>(
|
||||
context,
|
||||
context.resources.getQuantityString(R.plurals.ConversationFragment_saving_n_attachments, count, count),
|
||||
context.resources.getQuantityString(R.plurals.ConversationFragment_saving_n_attachments_to_sd_card, count, count)
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@ -41,30 +45,25 @@ class SaveAttachmentTask : ProgressDialogAsyncTask<SaveAttachmentTask.Attachment
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun showWarningDialog(context: Context, onAcceptListener: OnClickListener, count: Int = 1) {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setTitle(R.string.ConversationFragment_save_to_sd_card)
|
||||
builder.setIconAttribute(R.attr.dialog_alert_icon)
|
||||
builder.setCancelable(true)
|
||||
builder.setMessage(context.resources.getQuantityString(
|
||||
fun showWarningDialog(context: Context, count: Int = 1, onAcceptListener: () -> Unit = {}) {
|
||||
context.showSessionDialog {
|
||||
title(R.string.ConversationFragment_save_to_sd_card)
|
||||
iconAttribute(R.attr.dialog_alert_icon)
|
||||
text(context.resources.getQuantityString(
|
||||
R.plurals.ConversationFragment_saving_n_media_to_storage_warning,
|
||||
count,
|
||||
count))
|
||||
builder.setPositiveButton(R.string.yes, onAcceptListener)
|
||||
builder.setNegativeButton(R.string.no, null)
|
||||
builder.show()
|
||||
button(R.string.yes) { onAcceptListener() }
|
||||
button(R.string.no)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val contextReference: WeakReference<Context>
|
||||
private val attachmentCount: Int
|
||||
private val attachmentCount: Int = count
|
||||
|
||||
@JvmOverloads
|
||||
constructor(context: Context, count: Int = 1): super(context,
|
||||
context.resources.getQuantityString(R.plurals.ConversationFragment_saving_n_attachments, count, count),
|
||||
context.resources.getQuantityString(R.plurals.ConversationFragment_saving_n_attachments_to_sd_card, count, count)) {
|
||||
init {
|
||||
this.contextReference = WeakReference(context)
|
||||
this.attachmentCount = count
|
||||
}
|
||||
|
||||
override fun doInBackground(vararg attachments: Attachment?): Pair<Int, String?> {
|
||||
|
@ -1,57 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:elevation="4dp"
|
||||
android:padding="@dimen/medium_spacing">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/blockedTitleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_blocked_title"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/large_font_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/blockedExplanationTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="@string/dialog_blocked_explanation"
|
||||
android:paddingHorizontal="@dimen/medium_spacing"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/unblockButton"
|
||||
android:contentDescription="@string/AccessibilityId_block_confirm"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:text="@string/ConversationActivity_unblock" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:elevation="4dp"
|
||||
android:padding="@dimen/medium_spacing">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/downloadTitleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_download_title"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/large_font_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/downloadExplanationTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="@string/dialog_download_explanation"
|
||||
android:paddingHorizontal="@dimen/medium_spacing"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:contentDescription="@string/AccessibilityId_dont_download_media"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/downloadButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:contentDescription="@string/AccessibilityId_download_media"
|
||||
android:text="@string/dialog_download_button_title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:elevation="4dp"
|
||||
android:padding="@dimen/medium_spacing">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/joinOpenGroupTitleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_join_open_group_title"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/large_font_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/joinOpenGroupExplanationTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="@string/dialog_join_open_group_explanation"
|
||||
android:paddingHorizontal="@dimen/medium_spacing"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/joinButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:text="@string/open_group_invitation_view__join_accessibility_description" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,60 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:elevation="4dp"
|
||||
android:padding="@dimen/medium_spacing">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/linkPreviewDialogTitleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_link_preview_title"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/large_font_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/linkPreviewDialogExplanationTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="@string/dialog_link_preview_explanation"
|
||||
android:paddingHorizontal="@dimen/medium_spacing"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel"
|
||||
android:contentDescription="@string/AccessibilityId_cancel_link_preview_button"/>
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/enableLinkPreviewsButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:text="@string/dialog_link_preview_enable_button_title"
|
||||
android:contentDescription="@string/AccessibilityId_enable_link_preview_button"
|
||||
/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:elevation="4dp"
|
||||
android:padding="@dimen/medium_spacing">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/openURLTitleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_open_url_title"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/large_font_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/openURLExplanationTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="@string/dialog_open_url_explanation"
|
||||
android:paddingHorizontal="@dimen/medium_spacing"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/openURLButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:text="@string/open" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,69 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/medium_spacing">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_seed_title"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textAlignment="center"
|
||||
android:textSize="@dimen/medium_font_size" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="@string/dialog_seed_explanation"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/medium_font_size"
|
||||
android:textAlignment="center"
|
||||
android:alpha="0.6" />
|
||||
|
||||
<TextView
|
||||
style="@style/SessionIDTextView"
|
||||
android:contentDescription="@string/AccessibilityId_recovery_phrase"
|
||||
android:id="@+id/seedTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:padding="@dimen/small_spacing"
|
||||
tools:text="habitat kiwi amply iceberg dog nerves spiderman soft match partial awakened maximum degrees"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:contentDescription="@string/AccessibilityId_cancel_button"
|
||||
android:id="@+id/copyButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:text="@string/copy" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:contentDescription="@string/AccessibilityId_copy_recovery_phrase"
|
||||
android:id="@+id/closeButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/close" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:elevation="4dp"
|
||||
android:padding="@dimen/medium_spacing">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_share_logs_title"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/medium_font_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialogDescriptionText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="@string/dialog_share_logs_explanation"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.UnimportantText"
|
||||
android:id="@+id/shareButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:text="@string/share" />
|
||||
|
||||
<com.github.ybq.android.spinkit.SpinKitView
|
||||
style="@style/SpinKitView.Small.ThreeBounce"
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_weight="1"
|
||||
app:SpinKit_Color="?colorAccent"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -169,14 +169,6 @@
|
||||
<item>@string/arrays__use_custom</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="mute_durations">
|
||||
<item>@string/arrays__mute_for_one_hour</item>
|
||||
<item>@string/arrays__mute_for_two_hours</item>
|
||||
<item>@string/arrays__mute_for_one_day</item>
|
||||
<item>@string/arrays__mute_for_seven_days</item>
|
||||
<item>@string/arrays__mute_forever</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_notification_privacy_entries">
|
||||
<item>@string/arrays__name_and_message</item>
|
||||
<item>@string/arrays__name_only</item>
|
||||
|
@ -71,6 +71,7 @@
|
||||
|
||||
<!-- TODO These button styles require proper background selectors for up/down visual state. -->
|
||||
<style name="Widget.Session.Button.Common" parent="">
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:textSize">@dimen/medium_font_size</item>
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
@ -110,6 +111,7 @@
|
||||
</style>
|
||||
|
||||
<style name="Widget.Session.Button.Dialog" parent="">
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:textSize">@dimen/small_font_size</item>
|
||||
<item name="android:textColor">?android:textColorPrimary</item>
|
||||
|
Loading…
Reference in New Issue
Block a user