introduce settings activity

This commit is contained in:
Daniel Gultsch 2023-02-20 10:09:20 +01:00
parent cdcd323c36
commit fe9b3b8ed9
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
18 changed files with 197 additions and 47 deletions

View file

@ -88,6 +88,9 @@ dependencies {
implementation "androidx.room:room-guava:$rootProject.ext.roomVersion" implementation "androidx.room:room-guava:$rootProject.ext.roomVersion"
annotationProcessor "androidx.room:room-compiler:$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" implementation "androidx.security:security-crypto:1.0.0"

View file

@ -93,12 +93,15 @@
<activity <activity
android:name="im.conversations.android.ui.activity.MainActivity" android:name="im.conversations.android.ui.activity.MainActivity"
android:windowSoftInputMode="adjustResize"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name="im.conversations.android.ui.activity.SettingsActivity" />
<activity <activity
android:name="im.conversations.android.ui.activity.SetupActivity" android:name="im.conversations.android.ui.activity.SetupActivity"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />

View file

@ -2,6 +2,7 @@ package im.conversations.android;
import android.app.Application; import android.app.Application;
import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import com.google.android.material.color.DynamicColors;
import im.conversations.android.dns.Resolver; import im.conversations.android.dns.Resolver;
import im.conversations.android.notification.Channels; import im.conversations.android.notification.Channels;
import im.conversations.android.xmpp.ConnectionPool; import im.conversations.android.xmpp.ConnectionPool;
@ -31,6 +32,6 @@ public class Conversations extends Application {
ConnectionPool.getInstance(this).reconfigure(); ConnectionPool.getInstance(this).reconfigure();
AppCompatDelegate.setDefaultNightMode( AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); // For night mode theme AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); // For night mode theme
// DynamicColors.applyToActivitiesIfAvailable(this); DynamicColors.applyToActivitiesIfAvailable(this);
} }
} }

View file

@ -1,7 +1,6 @@
package im.conversations.android.database.model; package im.conversations.android.database.model;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
@ -33,9 +32,6 @@ public class AccountIdentifier implements ChatFilter {
@Override @Override
public String toString() { public String toString() {
return MoreObjects.toStringHelper(this) return MoreObjects.toStringHelper(this).add("id", id).add("address", address).toString();
.add("id", id)
.add("address", address)
.toString();
} }
} }

View file

@ -1,22 +1,15 @@
package im.conversations.android.database.model; package im.conversations.android.database.model;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import java.util.StringJoiner;
public class GroupIdentifier implements ChatFilter { public class GroupIdentifier implements ChatFilter {
public final long id; public final long id;
public final String name; public final String name;
@Override @Override
public String toString() { public String toString() {
return MoreObjects.toStringHelper(this) return MoreObjects.toStringHelper(this).add("id", id).add("name", name).toString();
.add("id", id)
.add("name", name)
.toString();
} }
public GroupIdentifier(long id, String name) { public GroupIdentifier(long id, String name) {

View file

@ -1,15 +1,11 @@
package im.conversations.android.ui; package im.conversations.android.ui;
import android.content.Intent; import android.content.Intent;
import com.google.common.base.Strings; 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.AccountIdentifier;
import im.conversations.android.database.model.ChatFilter; import im.conversations.android.database.model.ChatFilter;
import im.conversations.android.database.model.GroupIdentifier; import im.conversations.android.database.model.GroupIdentifier;
import org.jxmpp.jid.impl.JidCreate;
public final class Intents { public final class Intents {

View file

@ -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();
}
}

View file

@ -3,9 +3,11 @@ package im.conversations.android.ui.fragment.main;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil; import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; 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.database.model.GroupIdentifier;
import im.conversations.android.databinding.FragmentOverviewBinding; import im.conversations.android.databinding.FragmentOverviewBinding;
import im.conversations.android.ui.Intents; 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.activity.SetupActivity;
import im.conversations.android.ui.model.OverviewViewModel; import im.conversations.android.ui.model.OverviewViewModel;
import java.util.List; import java.util.List;
@ -55,24 +58,7 @@ public class OverviewFragment extends Fragment {
window.setStatusBarColor(SurfaceColors.SURFACE_0.getColor(activity)); window.setStatusBarColor(SurfaceColors.SURFACE_0.getColor(activity));
} }
}); });
binding.navigationView.setNavigationItemSelectedListener( binding.navigationView.setNavigationItemSelectedListener(this::onNavigationItemSelected);
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.setCheckedItem(R.id.chats); binding.navigationView.setCheckedItem(R.id.chats);
this.overviewViewModel this.overviewViewModel
.getAccounts() .getAccounts()
@ -84,6 +70,31 @@ public class OverviewFragment extends Fragment {
return binding.getRoot(); 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<? extends AppCompatActivity> activityClazz) {
startActivity(new Intent(requireContext(), activityClazz));
binding.drawerLayout.close();
return false;
}
private void setChatFilter(final ChatFilter chatFilter) { private void setChatFilter(final ChatFilter chatFilter) {
overviewViewModel.setChatFilter(chatFilter); overviewViewModel.setChatFilter(chatFilter);
binding.drawerLayout.close(); binding.drawerLayout.close();

View file

@ -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);
}
}

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.5,14.98c-0.02,0 -0.03,0 -0.05,0.01C21.2,13.3 19.76,12 18,12c-1.4,0 -2.6,0.83 -3.16,2.02C13.26,14.1 12,15.4 12,17c0,1.66 1.34,3 3,3l6.5,-0.02c1.38,0 2.5,-1.12 2.5,-2.5S22.88,14.98 21.5,14.98zM10,4.26v2.09C7.67,7.18 6,9.39 6,12c0,1.77 0.78,3.34 2,4.44V14h2v6H4v-2h2.73C5.06,16.54 4,14.4 4,12C4,8.27 6.55,5.15 10,4.26zM20,6h-2.73c1.43,1.26 2.41,3.01 2.66,5l-2.02,0C17.68,9.64 16.98,8.45 16,7.56V10h-2V4h6V6z" />
</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,2C6.49,2 2,6.49 2,12s4.49,10 10,10c1.38,0 2.5,-1.12 2.5,-2.5c0,-0.61 -0.23,-1.2 -0.64,-1.67c-0.08,-0.1 -0.13,-0.21 -0.13,-0.33c0,-0.28 0.22,-0.5 0.5,-0.5H16c3.31,0 6,-2.69 6,-6C22,6.04 17.51,2 12,2zM17.5,13c-0.83,0 -1.5,-0.67 -1.5,-1.5c0,-0.83 0.67,-1.5 1.5,-1.5s1.5,0.67 1.5,1.5C19,12.33 18.33,13 17.5,13zM14.5,9C13.67,9 13,8.33 13,7.5C13,6.67 13.67,6 14.5,6S16,6.67 16,7.5C16,8.33 15.33,9 14.5,9zM5,11.5C5,10.67 5.67,10 6.5,10S8,10.67 8,11.5C8,12.33 7.33,13 6.5,13S5,12.33 5,11.5zM11,7.5C11,8.33 10.33,9 9.5,9S8,8.33 8,7.5C8,6.67 8.67,6 9.5,6S11,6.67 11,7.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="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z" />
</vector>

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2019 Daniel Gultsch
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="false"
app:elevation="0dp">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/material_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/title_activity_settings"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

View file

@ -13,6 +13,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/searchbar_scrolling_view_behavior"/>
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout" android:id="@+id/app_bar_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -29,6 +34,15 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/extended_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|end"
android:text="@string/start_chat"
app:icon="@drawable/ic_chat_24dp"/>
<com.google.android.material.search.SearchView <com.google.android.material.search.SearchView
android:id="@+id/search_view" android:id="@+id/search_view"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -38,14 +52,6 @@
app:useDrawerArrowDrawable="true"> app:useDrawerArrowDrawable="true">
<!-- Search suggestions/results go here (ScrollView, RecyclerView, etc.). --> <!-- Search suggestions/results go here (ScrollView, RecyclerView, etc.). -->
</com.google.android.material.search.SearchView> </com.google.android.material.search.SearchView>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/extended_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|end"
android:text="@string/start_chat"
app:icon="@drawable/ic_chat_24dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1017,5 +1017,10 @@
<string name="accounts">Accounts</string> <string name="accounts">Accounts</string>
<string name="spaces">Spaces</string> <string name="spaces">Spaces</string>
<string name="chats">Chats</string> <string name="chats">Chats</string>
<string name="pref_title_appearance">Appearance</string>
<string name="pref_summary_appearance"><![CDATA[Theme & Colors]]></string>
<string name="pref_title_security">Security</string>
<string name="pref_summary_security">Encryption, Blind Trust Before Verification, MIM Detection</string>
<string name="unified_push_summary">Notification relay for UnifiedPush compatible third party apps</string>
</resources> </resources>

View file

@ -27,5 +27,6 @@
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item> <item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item> <item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_light_inversePrimary</item> <item name="colorPrimaryInverse">@color/md_theme_light_inversePrimary</item>
<item name="android:statusBarColor">?colorSurface</item>
</style> </style>
</resources> </resources>

View file

@ -0,0 +1,20 @@
<?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">
<Preference
app:title="@string/pref_title_appearance"
app:summary="@string/pref_summary_appearance"
android:icon="@drawable/ic_palette_24dp"
app:fragment="im.conversations.android.ui.fragment.MainSettingsFragment"/>
<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.MainSettingsFragment"/>
<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"/>
</PreferenceScreen>

View file

@ -5,6 +5,7 @@ buildscript {
lifecycleVersion = "2.2.0" lifecycleVersion = "2.2.0"
navVersion = '2.5.3' navVersion = '2.5.3'
roomVersion = "2.5.0" roomVersion = "2.5.0"
preferenceVersion = "1.2.0"
espressoVersion = "3.5.1" espressoVersion = "3.5.1"
} }