add notifications and attachments settings screens

This commit is contained in:
Daniel Gultsch 2023-02-23 13:41:35 +01:00
parent bfafad6c65
commit 44ac7190a9
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
19 changed files with 406 additions and 10 deletions

View file

@ -0,0 +1,41 @@
package im.conversations.android.ui.activity.result;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class PickRingtone extends ActivityResultContract<Uri, Uri> {
private static final Uri NONE = Uri.parse("about:blank");
@NonNull
@Override
public Intent createIntent(@NonNull final Context context, final Uri existing) {
final Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
if (existing != null) {
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, existing);
}
return intent;
}
@Override
public Uri parseResult(int resultCode, @Nullable Intent data) {
if (resultCode != Activity.RESULT_OK || data == null) {
return null;
}
final Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
return pickedUri == null ? NONE : pickedUri;
}
public static Uri noneToNull(final Uri uri) {
return uri == null || NONE.equals(uri) ? null : uri;
}
}

View file

@ -0,0 +1,20 @@
package im.conversations.android.ui.fragment.settings;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceFragmentCompat;
import im.conversations.android.R;
public class AttachmentsSettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
setPreferencesFromResource(R.xml.preferences_attachments, rootKey);
}
@Override
public void onStart() {
super.onStart();
requireActivity().setTitle(R.string.pref_attachments);
}
}

View file

@ -3,6 +3,7 @@ package im.conversations.android.ui.fragment.settings;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceFragmentCompat;
import im.conversations.android.BuildConfig;
import im.conversations.android.R;
public class MainSettingsFragment extends PreferenceFragmentCompat {
@ -10,6 +11,12 @@ public class MainSettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
setPreferencesFromResource(R.xml.preferences_main, rootKey);
final var about = findPreference("about");
if (about == null) {
throw new IllegalStateException("The preference resource file did not 'about'");
}
about.setTitle(getString(R.string.title_activity_about_x, BuildConfig.APP_NAME));
about.setSummary(String.format("%s %s", BuildConfig.APP_NAME, BuildConfig.VERSION_NAME));
}
@Override

View file

@ -0,0 +1,80 @@
package im.conversations.android.ui.fragment.settings;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import com.google.common.base.Strings;
import im.conversations.android.R;
import im.conversations.android.ui.activity.result.PickRingtone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NotificationsSettingsFragment extends PreferenceFragmentCompat {
private static final String RINGTONE_PREFERENCE_KEY = "call_ringtone";
private static final Logger LOGGER =
LoggerFactory.getLogger(NotificationsSettingsFragment.class);
private final ActivityResultLauncher<Uri> pickRingtoneLauncher =
registerForActivityResult(
new PickRingtone(),
result -> {
if (result == null) {
// do nothing. user aborted
return;
}
final Uri uri = PickRingtone.noneToNull(result);
setRingtone(uri);
LOGGER.info("User set ringtone to {}", uri);
});
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
setPreferencesFromResource(R.xml.preferences_notifications, rootKey);
}
@Override
public void onStart() {
super.onStart();
requireActivity().setTitle(R.string.notifications);
}
@Override
public boolean onPreferenceTreeClick(final Preference preference) {
if (RINGTONE_PREFERENCE_KEY.equals(preference.getKey())) {
pickRingtone();
return true;
}
return super.onPreferenceTreeClick(preference);
}
private void pickRingtone() {
final SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext());
final String incomingCallRingtone =
sharedPreferences.getString(
RINGTONE_PREFERENCE_KEY,
requireContext().getString(R.string.incoming_call_ringtone));
final Uri uri =
Strings.isNullOrEmpty(incomingCallRingtone)
? null
: Uri.parse(incomingCallRingtone);
LOGGER.info("current ringtone {}", uri);
this.pickRingtoneLauncher.launch(uri);
}
private void setRingtone(final Uri uri) {
final SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext());
sharedPreferences
.edit()
.putString(RINGTONE_PREFERENCE_KEY, uri == null ? null : uri.toString())
.apply();
}
}

View file

@ -0,0 +1,20 @@
package im.conversations.android.ui.fragment.settings;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceFragmentCompat;
import im.conversations.android.R;
public class UpSettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
setPreferencesFromResource(R.xml.preferences_up, rootKey);
}
@Override
public void onStart() {
super.onStart();
requireActivity().setTitle(R.string.unified_push_distributor);
}
}

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M2,12.5C2,9.46 4.46,7 7.5,7H18c2.21,0 4,1.79 4,4s-1.79,4 -4,4H9.5C8.12,15 7,13.88 7,12.5S8.12,10 9.5,10H17v2H9.41c-0.55,0 -0.55,1 0,1H18c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2H7.5C5.57,9 4,10.57 4,12.5S5.57,16 7.5,16H17v2H7.5C4.46,18 2,15.54 2,12.5z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M5,20h14v-2H5V20zM19,9h-4V3H9v6H5l7,7L19,9z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M18,4l2,4h-3l-2,-4h-2l2,4h-3l-2,-4H8l2,4H7L5,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V4h-4z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.93 6,11v5l-2,2v1h16v-1l-2,-2zM14.5,9.8l-2.8,3.4h2.8L14.5,15h-5v-1.8l2.8,-3.4L9.5,9.8L9.5,8h5v1.8z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1 -9.39,0 -17,-7.61 -17,-17 0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
</vector>

View file

@ -5,6 +5,10 @@
<bool name="enter_is_send">false</bool>
<bool name="allow_screenshots">true</bool>
<bool name="btbv">true</bool>
<string translatable="false" name="omemo_setting_default">default_on</string>
<string name="omemo_setting_default" translatable="false">default_on</string>
<string name="incoming_call_ringtone" translatable="false">content://settings/system/ringtone</string>
<integer name="grace_period">144</integer>
<integer name="auto_accept_filesize">524288</integer>
<string name="picture_compression" translatable="false">auto</string>
<integer name="video_compression">360</integer>
</resources>

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- security -->
<string-array name="omemo_setting_entry_values">
<item>always</item>
<item>default_on</item>
@ -12,4 +14,65 @@
<item>@string/default_off</item>
</string-array>
<!-- notifications -->
<string-array name="grace_periods">
<item>@string/gp_disable</item>
<item>@string/gp_short</item>
<item>@string/gp_medium</item>
<item>@string/gp_long</item>
</string-array>
<string-array name="grace_periods_values">
<item>0</item>
<item>144</item>
<item>610</item>
<item>2584</item>
</string-array>
<!-- attachments -->
<string-array name="filesizes">
<item>@string/never</item>
<item>256 KiB</item>
<item>512 KiB</item>
<item>1 MiB</item>
<item>5 MiB</item>
<item>10 MiB</item>
</string-array>
<string-array name="filesizes_values">
<item>0</item>
<item>262144</item>
<item>524288</item>
<item>1048576</item>
<item>5242880</item>
<item>10485760</item>
</string-array>
<string-array name="picture_compression_values">
<item>never</item>
<item>auto</item>
<item>always</item>
</string-array>
<string-array name="picture_compression_entries">
<item>@string/never</item>
<item>@string/large_images_only</item>
<item>@string/always</item>
</string-array>
<string-array name="video_compression_values">
<item>360</item>
<item>720</item>
<item>uncompressed</item>
</string-array>
<string-array name="video_compression_entries">
<item>@string/video_360p</item>
<item>@string/video_720p</item>
<item>@string/video_original</item>
</string-array>
</resources>

View file

@ -1032,5 +1032,11 @@
<string name="pref_category_server_connection">Server connection</string>
<string name="detect_mim">Require channel binding</string>
<string name="detect_mim_summary">Channel binding can detect some machine-in-the-middle attacks</string>
<string name="notifications">Notifications</string>
<string name="pref_attachments_summary">File size, Image compression, Video quality</string>
<string name="pref_notifications_summary">Grace period, Ringtone, Vibration, Strangers</string>
<string name="pref_automatic_download">Automatic download</string>
<string name="pref_category_sending">Sending</string>
<string name="pref_category_receiving">Receiving</string>
</resources>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="@string/pref_category_sending">
<ListPreference
android:defaultValue="@string/picture_compression"
android:entries="@array/picture_compression_entries"
android:entryValues="@array/picture_compression_values"
android:icon="@drawable/ic_photo_24dp"
android:key="picture_compression"
android:title="@string/pref_picture_compression"
app:useSimpleSummaryProvider="true" />
<ListPreference
android:defaultValue="@integer/video_compression"
android:entries="@array/video_compression_entries"
android:entryValues="@array/video_compression_values"
android:icon="@drawable/ic_movie_24dp"
android:key="video_compression"
android:title="@string/pref_video_compression"
app:useSimpleSummaryProvider="true" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_receiving">
<ListPreference
android:defaultValue="@integer/auto_accept_filesize"
android:entries="@array/filesizes"
android:entryValues="@array/filesizes_values"
android:icon="@drawable/ic_download_24dp"
android:key="auto_accept_file_size"
android:title="@string/pref_automatic_download"
app:useSimpleSummaryProvider="true" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -2,19 +2,32 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
app:title="@string/pref_title_interface"
app:summary="@string/pref_summary_appearance"
android:icon="@drawable/ic_touch_app_24dp"
app:fragment="im.conversations.android.ui.fragment.settings.InterfaceSettingsFragment"/>
app:fragment="im.conversations.android.ui.fragment.settings.InterfaceSettingsFragment"
app:summary="@string/pref_summary_appearance"
app:title="@string/pref_title_interface" />
<Preference
app:title="@string/pref_title_security"
app:summary="@string/pref_summary_security"
android:icon="@drawable/ic_security_24dp"
app:fragment="im.conversations.android.ui.fragment.settings.SecuritySettingsFragment"/>
app:fragment="im.conversations.android.ui.fragment.settings.SecuritySettingsFragment"
app:summary="@string/pref_summary_security"
app:title="@string/pref_title_security" />
<Preference
android:icon="@drawable/ic_notifications_24dp"
android:summary="@string/pref_notifications_summary"
android:title="@string/notifications"
app:fragment="im.conversations.android.ui.fragment.settings.NotificationsSettingsFragment" />
<Preference
android:icon="@drawable/ic_attachment_24dp"
android:summary="@string/pref_attachments_summary"
android:title="@string/pref_attachments"
app:fragment="im.conversations.android.ui.fragment.settings.AttachmentsSettingsFragment" />
<Preference
app:title="@string/unified_push_distributor"
app:summary="@string/unified_push_summary"
android:icon="@drawable/ic_cloud_sync_24dp"
app:fragment="im.conversations.android.ui.fragment.MainSettingsFragment"/>
app:fragment="im.conversations.android.ui.fragment.settings.UpSettingsFragment"
app:summary="@string/unified_push_summary"
app:title="@string/unified_push_distributor" />
<Preference android:key="about" android:title="@string/title_activity_about_x">
</Preference>
</PreferenceScreen>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen
android:icon="@drawable/ic_chat_24dp"
android:key="message_notification_settings"
android:summary="@string/pref_more_notification_settings_summary"
android:title="@string/pref_message_notification_settings">
<intent android:action="android.settings.CHANNEL_NOTIFICATION_SETTINGS">
<extra
android:name="android.provider.extra.APP_PACKAGE"
android:value="@string/applicationId" />
<extra
android:name="android.provider.extra.CHANNEL_ID"
android:value="foreground" />
</intent>
</PreferenceScreen>
<Preference
android:icon="@drawable/ic_phone_24dp"
android:key="call_ringtone"
android:ringtoneType="ringtone"
android:summary="@string/pref_call_ringtone_summary"
android:title="@string/pref_ringtone" />
<ListPreference
android:defaultValue="@integer/grace_period"
android:entries="@array/grace_periods"
android:entryValues="@array/grace_periods_values"
android:icon="@drawable/ic_notifications_paused_24dp"
android:key="grace_period_length"
android:summary="@string/pref_notification_grace_period_summary"
android:title="@string/pref_notification_grace_period" />
<SwitchPreferenceCompat
android:defaultValue="@bool/notifications_from_strangers"
android:key="notifications_from_strangers"
android:summary="@string/pref_notifications_from_strangers_summary"
android:title="@string/pref_notifications_from_strangers" />
</PreferenceScreen>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
</PreferenceScreen>