diff --git a/app/build.gradle b/app/build.gradle index 86bece7a0..a5a1b0d96 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,6 +88,9 @@ dependencies { implementation "androidx.room:room-guava:$rootProject.ext.roomVersion" annotationProcessor "androidx.room:room-compiler:$rootProject.ext.roomVersion" + implementation "androidx.preference:preference:$rootProject.ext.preferenceVersion" + + implementation "androidx.security:security-crypto:1.0.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 37564f17e..f4b2fd334 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -93,12 +93,15 @@ + diff --git a/app/src/main/java/im/conversations/android/Conversations.java b/app/src/main/java/im/conversations/android/Conversations.java index 9108693fc..c7982790b 100644 --- a/app/src/main/java/im/conversations/android/Conversations.java +++ b/app/src/main/java/im/conversations/android/Conversations.java @@ -2,6 +2,7 @@ package im.conversations.android; import android.app.Application; import androidx.appcompat.app.AppCompatDelegate; +import com.google.android.material.color.DynamicColors; import im.conversations.android.dns.Resolver; import im.conversations.android.notification.Channels; import im.conversations.android.xmpp.ConnectionPool; @@ -31,6 +32,6 @@ public class Conversations extends Application { ConnectionPool.getInstance(this).reconfigure(); AppCompatDelegate.setDefaultNightMode( AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); // For night mode theme - // DynamicColors.applyToActivitiesIfAvailable(this); + DynamicColors.applyToActivitiesIfAvailable(this); } } diff --git a/app/src/main/java/im/conversations/android/database/model/AccountIdentifier.java b/app/src/main/java/im/conversations/android/database/model/AccountIdentifier.java index 08ab3e664..048a321cc 100644 --- a/app/src/main/java/im/conversations/android/database/model/AccountIdentifier.java +++ b/app/src/main/java/im/conversations/android/database/model/AccountIdentifier.java @@ -1,7 +1,6 @@ package im.conversations.android.database.model; import androidx.annotation.NonNull; - import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import com.google.common.base.Preconditions; @@ -33,9 +32,6 @@ public class AccountIdentifier implements ChatFilter { @Override public String toString() { - return MoreObjects.toStringHelper(this) - .add("id", id) - .add("address", address) - .toString(); + return MoreObjects.toStringHelper(this).add("id", id).add("address", address).toString(); } } diff --git a/app/src/main/java/im/conversations/android/database/model/GroupIdentifier.java b/app/src/main/java/im/conversations/android/database/model/GroupIdentifier.java index c8e125f44..f260ba6b1 100644 --- a/app/src/main/java/im/conversations/android/database/model/GroupIdentifier.java +++ b/app/src/main/java/im/conversations/android/database/model/GroupIdentifier.java @@ -1,22 +1,15 @@ package im.conversations.android.database.model; import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; - -import java.util.StringJoiner; public class GroupIdentifier implements ChatFilter { public final long id; public final String name; - @Override public String toString() { - return MoreObjects.toStringHelper(this) - .add("id", id) - .add("name", name) - .toString(); + return MoreObjects.toStringHelper(this).add("id", id).add("name", name).toString(); } public GroupIdentifier(long id, String name) { diff --git a/app/src/main/java/im/conversations/android/ui/Intents.java b/app/src/main/java/im/conversations/android/ui/Intents.java index 2fcfc84b3..fc2aae3fc 100644 --- a/app/src/main/java/im/conversations/android/ui/Intents.java +++ b/app/src/main/java/im/conversations/android/ui/Intents.java @@ -1,15 +1,11 @@ package im.conversations.android.ui; import android.content.Intent; - import com.google.common.base.Strings; - -import org.jxmpp.jid.BareJid; -import org.jxmpp.jid.impl.JidCreate; - import im.conversations.android.database.model.AccountIdentifier; import im.conversations.android.database.model.ChatFilter; import im.conversations.android.database.model.GroupIdentifier; +import org.jxmpp.jid.impl.JidCreate; public final class Intents { @@ -47,7 +43,7 @@ public final class Intents { throw new IllegalArgumentException("Intent doe not specify an action"); } if (ACTION_FILTER_CHATS_BY_ACCOUNT.equals(action)) { - final var id = intent.getLongExtra(EXTRA_ACCOUNT_ID,-1); + final var id = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1); final var address = intent.getStringExtra(EXTRA_ACCOUNT_ADDRESS); if (id < 0 || Strings.isNullOrEmpty(address)) { throw new IllegalArgumentException("account filter intent lacks extras"); @@ -55,7 +51,7 @@ public final class Intents { return new AccountIdentifier(id, JidCreate.bareFromOrThrowUnchecked(address)); } if (ACTION_FILTER_CHATS_BY_GROUP.equals(action)) { - final var id = intent.getLongExtra(EXTRA_GROUP_ID,-1); + final var id = intent.getLongExtra(EXTRA_GROUP_ID, -1); final var name = intent.getStringExtra(EXTRA_GROUP_NAME); if (id < 0 || Strings.isNullOrEmpty(name)) { throw new IllegalArgumentException("group filter intent lack address"); diff --git a/app/src/main/java/im/conversations/android/ui/activity/SettingsActivity.java b/app/src/main/java/im/conversations/android/ui/activity/SettingsActivity.java new file mode 100644 index 000000000..34d2e7a56 --- /dev/null +++ b/app/src/main/java/im/conversations/android/ui/activity/SettingsActivity.java @@ -0,0 +1,27 @@ +package im.conversations.android.ui.activity; + +import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.databinding.DataBindingUtil; +import im.conversations.android.R; +import im.conversations.android.databinding.ActivitySettingsBinding; +import im.conversations.android.service.ForegroundService; +import im.conversations.android.ui.Activities; +import im.conversations.android.ui.fragment.settings.MainSettingsFragment; + +public class SettingsActivity extends AppCompatActivity { + + private ActivitySettingsBinding binding; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ForegroundService.start(this); + this.binding = DataBindingUtil.setContentView(this, R.layout.activity_settings); + Activities.setStatusAndNavigationBarColors(this, binding.getRoot()); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, new MainSettingsFragment()) + .commit(); + } +} diff --git a/app/src/main/java/im/conversations/android/ui/fragment/main/OverviewFragment.java b/app/src/main/java/im/conversations/android/ui/fragment/main/OverviewFragment.java index 19b14c38d..368238ff6 100644 --- a/app/src/main/java/im/conversations/android/ui/fragment/main/OverviewFragment.java +++ b/app/src/main/java/im/conversations/android/ui/fragment/main/OverviewFragment.java @@ -3,9 +3,11 @@ package im.conversations.android.ui.fragment.main; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; import androidx.databinding.DataBindingUtil; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; @@ -17,6 +19,7 @@ import im.conversations.android.database.model.ChatFilter; import im.conversations.android.database.model.GroupIdentifier; import im.conversations.android.databinding.FragmentOverviewBinding; import im.conversations.android.ui.Intents; +import im.conversations.android.ui.activity.SettingsActivity; import im.conversations.android.ui.activity.SetupActivity; import im.conversations.android.ui.model.OverviewViewModel; import java.util.List; @@ -55,24 +58,7 @@ public class OverviewFragment extends Fragment { window.setStatusBarColor(SurfaceColors.SURFACE_0.getColor(activity)); } }); - binding.navigationView.setNavigationItemSelectedListener( - item -> { - if (item.getItemId() == R.id.chats) { - setChatFilter(null); - return true; - } - if (item.getItemId() == R.id.add_account) { - startActivity(new Intent(requireContext(), SetupActivity.class)); - binding.drawerLayout.close(); - return false; - } - final var intent = item.getIntent(); - if (intent == null) { - return false; - } - setChatFilter(Intents.toChatFilter(intent)); - return true; - }); + binding.navigationView.setNavigationItemSelectedListener(this::onNavigationItemSelected); binding.navigationView.setCheckedItem(R.id.chats); this.overviewViewModel .getAccounts() @@ -84,6 +70,31 @@ public class OverviewFragment extends Fragment { return binding.getRoot(); } + private boolean onNavigationItemSelected(final MenuItem menuItem) { + if (menuItem.getItemId() == R.id.chats) { + setChatFilter(null); + return true; + } + if (menuItem.getItemId() == R.id.add_account) { + return startActivity(SetupActivity.class); + } + if (menuItem.getItemId() == R.id.settings) { + return startActivity(SettingsActivity.class); + } + final var intent = menuItem.getIntent(); + if (intent == null) { + return false; + } + setChatFilter(Intents.toChatFilter(intent)); + return true; + } + + private boolean startActivity(final Class activityClazz) { + startActivity(new Intent(requireContext(), activityClazz)); + binding.drawerLayout.close(); + return false; + } + private void setChatFilter(final ChatFilter chatFilter) { overviewViewModel.setChatFilter(chatFilter); binding.drawerLayout.close(); diff --git a/app/src/main/java/im/conversations/android/ui/fragment/settings/MainSettingsFragment.java b/app/src/main/java/im/conversations/android/ui/fragment/settings/MainSettingsFragment.java new file mode 100644 index 000000000..dd6723206 --- /dev/null +++ b/app/src/main/java/im/conversations/android/ui/fragment/settings/MainSettingsFragment.java @@ -0,0 +1,14 @@ +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 MainSettingsFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + setPreferencesFromResource(R.xml.preferences_main, rootKey); + } +} diff --git a/app/src/main/res/drawable/ic_cloud_sync_24dp.xml b/app/src/main/res/drawable/ic_cloud_sync_24dp.xml new file mode 100644 index 000000000..80946e60e --- /dev/null +++ b/app/src/main/res/drawable/ic_cloud_sync_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_palette_24dp.xml b/app/src/main/res/drawable/ic_palette_24dp.xml new file mode 100644 index 000000000..22ec97312 --- /dev/null +++ b/app/src/main/res/drawable/ic_palette_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_security_24dp.xml b/app/src/main/res/drawable/ic_security_24dp.xml new file mode 100644 index 000000000..5a77cae5b --- /dev/null +++ b/app/src/main/res/drawable/ic_security_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml new file mode 100644 index 000000000..0ae23458a --- /dev/null +++ b/app/src/main/res/layout/activity_settings.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_overview.xml b/app/src/main/res/layout/fragment_overview.xml index 0a963ce9b..6acec49a1 100644 --- a/app/src/main/res/layout/fragment_overview.xml +++ b/app/src/main/res/layout/fragment_overview.xml @@ -13,6 +13,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bc62d3cf9..57f688ecb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1017,5 +1017,10 @@ Accounts Spaces Chats + Appearance + + Security + Encryption, Blind Trust Before Verification, MIM Detection + Notification relay for UnifiedPush compatible third party apps diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index ddf74586f..0b6f615bf 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -27,5 +27,6 @@ @color/md_theme_light_inverseOnSurface @color/md_theme_light_inverseSurface @color/md_theme_light_inversePrimary + ?colorSurface diff --git a/app/src/main/res/xml/preferences_main.xml b/app/src/main/res/xml/preferences_main.xml new file mode 100644 index 000000000..feb62cbfb --- /dev/null +++ b/app/src/main/res/xml/preferences_main.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 5170846e3..a45556429 100644 --- a/build.gradle +++ b/build.gradle @@ -5,6 +5,7 @@ buildscript { lifecycleVersion = "2.2.0" navVersion = '2.5.3' roomVersion = "2.5.0" + preferenceVersion = "1.2.0" espressoVersion = "3.5.1" }