diff --git a/app/build.gradle b/app/build.gradle index 80fae7a4..fd963943 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,6 +41,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta5' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.vectordrawable:vectordrawable:1.1.0' + implementation 'androidx.preference:preference:1.1.0-rc01' testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index eefcbdad..314b2b1e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,6 +41,10 @@ android:name=".log.LogsActivity" android:label="@string/title_activity_logs" android:theme="@style/AppTheme.NoActionBar" /> + diff --git a/app/src/main/java/com/github/gotify/init/InitializationActivity.java b/app/src/main/java/com/github/gotify/init/InitializationActivity.java index 2e8df5c6..b43b067b 100644 --- a/app/src/main/java/com/github/gotify/init/InitializationActivity.java +++ b/app/src/main/java/com/github/gotify/init/InitializationActivity.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.PreferenceManager; import com.github.gotify.NotificationSupport; import com.github.gotify.R; import com.github.gotify.Settings; @@ -21,6 +22,7 @@ import com.github.gotify.login.LoginActivity; import com.github.gotify.messages.MessagesActivity; import com.github.gotify.service.WebSocketService; +import com.github.gotify.settings.ThemeHelper; import static com.github.gotify.api.Callback.callInUI; @@ -31,6 +33,13 @@ public class InitializationActivity extends AppCompatActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.init(this); + String theme = + PreferenceManager.getDefaultSharedPreferences(this) + .getString( + getString(R.string.setting_key_theme), + getString(R.string.theme_default)); + ThemeHelper.setTheme(this, theme); + setContentView(R.layout.splash); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/app/src/main/java/com/github/gotify/login/LoginActivity.java b/app/src/main/java/com/github/gotify/login/LoginActivity.java index 235d96fd..a57f2737 100644 --- a/app/src/main/java/com/github/gotify/login/LoginActivity.java +++ b/app/src/main/java/com/github/gotify/login/LoginActivity.java @@ -14,6 +14,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.view.ContextThemeWrapper; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -135,7 +136,7 @@ public void doCheckUrl() { } public void showHttpWarning() { - new AlertDialog.Builder(this) + new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AppTheme_Dialog)) .setTitle(R.string.warning) .setCancelable(true) .setMessage(R.string.http_warning) @@ -273,7 +274,7 @@ private void newClientDialog(ApiClient client) { EditText clientName = new EditText(this); clientName.setText(Build.MODEL); - new AlertDialog.Builder(this) + new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AppTheme_Dialog)) .setTitle(R.string.create_client_title) .setMessage(R.string.create_client_message) .setView(clientName) diff --git a/app/src/main/java/com/github/gotify/messages/MessagesActivity.java b/app/src/main/java/com/github/gotify/messages/MessagesActivity.java index 4ce3bc5c..3522dd54 100644 --- a/app/src/main/java/com/github/gotify/messages/MessagesActivity.java +++ b/app/src/main/java/com/github/gotify/messages/MessagesActivity.java @@ -22,6 +22,7 @@ import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; @@ -61,6 +62,7 @@ import com.github.gotify.messages.provider.MessageWithImage; import com.github.gotify.picasso.PicassoDataRequestHandler; import com.github.gotify.service.WebSocketService; +import com.github.gotify.settings.SettingsActivity; import com.google.android.material.navigation.NavigationView; import com.google.android.material.snackbar.BaseTransientBottomBar; import com.google.android.material.snackbar.Snackbar; @@ -309,7 +311,7 @@ public boolean onNavigationItemSelected(MenuItem item) { startLoading(); toolbar.setSubtitle(""); } else if (id == R.id.logout) { - new AlertDialog.Builder(this) + new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AppTheme_Dialog)) .setTitle(R.string.logout) .setMessage(getString(R.string.logout_confirm)) .setPositiveButton(R.string.yes, this::doLogout) @@ -317,6 +319,8 @@ public boolean onNavigationItemSelected(MenuItem item) { .show(); } else if (id == R.id.nav_logs) { startActivity(new Intent(this, LogsActivity.class)); + } else if (id == R.id.settings) { + startActivity(new Intent(this, SettingsActivity.class)); } drawer.closeDrawer(GravityCompat.START); @@ -326,6 +330,7 @@ public boolean onNavigationItemSelected(MenuItem item) { public void doLogout(DialogInterface dialog, int which) { setContentView(R.layout.splash); new DeleteClientAndNavigateToLogin().execute(); + finish(); } private void startLoading() { diff --git a/app/src/main/java/com/github/gotify/settings/SettingsActivity.java b/app/src/main/java/com/github/gotify/settings/SettingsActivity.java new file mode 100644 index 00000000..b7340792 --- /dev/null +++ b/app/src/main/java/com/github/gotify/settings/SettingsActivity.java @@ -0,0 +1,56 @@ +package com.github.gotify.settings; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.MenuItem; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; +import com.github.gotify.R; + +public class SettingsActivity extends AppCompatActivity + implements SharedPreferences.OnSharedPreferenceChangeListener { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.settings_activity); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.settings, new SettingsFragment()) + .commit(); + setSupportActionBar(findViewById(R.id.toolbar)); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayShowCustomEnabled(true); + } + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + sharedPreferences.registerOnSharedPreferenceChangeListener(this); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (getString(R.string.setting_key_theme).equals(key)) { + ThemeHelper.setTheme( + this, sharedPreferences.getString(key, getString(R.string.theme_default))); + } + } + + public static class SettingsFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.root_preferences, rootKey); + } + } +} diff --git a/app/src/main/java/com/github/gotify/settings/ThemeHelper.java b/app/src/main/java/com/github/gotify/settings/ThemeHelper.java new file mode 100644 index 00000000..58af750c --- /dev/null +++ b/app/src/main/java/com/github/gotify/settings/ThemeHelper.java @@ -0,0 +1,27 @@ +package com.github.gotify.settings; + +import android.content.Context; +import android.os.Build; +import androidx.appcompat.app.AppCompatDelegate; +import com.github.gotify.R; + +public final class ThemeHelper { + private ThemeHelper() {} + + public static void setTheme(Context context, String newTheme) { + AppCompatDelegate.setDefaultNightMode(ofKey(context, newTheme)); + } + + private static int ofKey(Context context, String newTheme) { + if (context.getString(R.string.theme_dark).equals(newTheme)) { + return AppCompatDelegate.MODE_NIGHT_YES; + } + if (context.getString(R.string.theme_light).equals(newTheme)) { + return AppCompatDelegate.MODE_NIGHT_NO; + } + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { + return AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; + } + return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; + } +} diff --git a/app/src/main/res/drawable/gradient.xml b/app/src/main/res/drawable/gradient.xml deleted file mode 100644 index 5f41b34e..00000000 --- a/app/src/main/res/drawable/gradient.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml index 4522aca8..a087c86c 100644 --- a/app/src/main/res/drawable/ic_settings.xml +++ b/app/src/main/res/drawable/ic_settings.xml @@ -1,4 +1,6 @@ - + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 16565ace..1ce90e87 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -6,22 +6,22 @@ android:layout_height="match_parent" android:fillViewport="true"> -