Add option to change times that are used to switch to light/dark theme (#932)

### Describe what your pull request does and which issue you’re targeting
Closes #928

This allows to select the time to switch between themes. The mentioned color/contrast problem with the time selection isn't fixed. I also simplified the settings code (0fe854fd49). And with [this](a590f5bc4c) GitNex hides the two options to change the time if your theme isn't `Auto (Light/Dark)` or `Auto (Retro/Dark)`. I could apply this also to the notifications settings, that means that the advanced settings for notifications (polling delay, light...) are hidden if the notifications aren't enabled.

this is ready to review/merge
<br><br>

<!-- Make sure you are targeting the "main" branch, pull requests on release branches are only allowed for bug fixes. -->

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/932
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
This commit is contained in:
qwerty287 2021-08-02 18:59:30 +02:00 committed by M M Arif
parent 36f20bb1aa
commit 5544ae4248
8 changed files with 190 additions and 40 deletions

View File

@ -38,7 +38,7 @@ public abstract class BaseActivity extends AppCompatActivity {
break;
case 2:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
if(TimeHelper.timeBetweenHours(tinyDB.getInt("darkThemeTimeHour"), tinyDB.getInt("lightThemeTimeHour"), tinyDB.getInt("darkThemeTimeMinute"), tinyDB.getInt("lightThemeTimeMinute"))) {
tinyDB.putString("currentTheme", "dark");
setTheme(R.style.AppTheme);
@ -55,7 +55,7 @@ public abstract class BaseActivity extends AppCompatActivity {
setTheme(R.style.AppThemeRetro);
break;
case 4:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
if(TimeHelper.timeBetweenHours(tinyDB.getInt("darkThemeTimeHour"), tinyDB.getInt("lightThemeTimeHour"), tinyDB.getInt("darkThemeTimeMinute"), tinyDB.getInt("lightThemeTimeMinute"))) {
tinyDB.putString("currentTheme", "dark");
setTheme(R.style.AppTheme);

View File

@ -1,14 +1,20 @@
package org.mian.gitnex.activities;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TimePicker;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import com.google.android.material.switchmaterial.SwitchMaterial;
import org.jetbrains.annotations.NotNull;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsAppearanceBinding;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
/**
@ -38,13 +44,11 @@ public class SettingsAppearanceActivity extends BaseActivity {
ImageView closeActivity = activitySettingsAppearanceBinding.close;
final TextView tvDateTimeSelected = activitySettingsAppearanceBinding.tvDateTimeSelected; // setter for time
final TextView customFontSelected = activitySettingsAppearanceBinding.customFontSelected; // setter for custom font
final TextView themeSelected = activitySettingsAppearanceBinding.themeSelected; // setter for theme
LinearLayout timeFrame = activitySettingsAppearanceBinding.timeFrame;
LinearLayout customFontFrame = activitySettingsAppearanceBinding.customFontFrame;
LinearLayout themeFrame = activitySettingsAppearanceBinding.themeSelectionFrame;
LinearLayout lightTimeFrame = activitySettingsAppearanceBinding.lightThemeTimeSelectionFrame;
LinearLayout darkTimeFrame = activitySettingsAppearanceBinding.darkThemeTimeSelectionFrame;
SwitchMaterial counterBadgesSwitch = activitySettingsAppearanceBinding.switchCounterBadge;
@ -55,35 +59,36 @@ public class SettingsAppearanceActivity extends BaseActivity {
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(!tinyDB.getString("timeStr").isEmpty()) {
String lightMinute = String.valueOf(tinyDB.getInt("lightThemeTimeMinute"));
String lightHour = String.valueOf(tinyDB.getInt("lightThemeTimeHour"));
if(lightMinute.length() == 1) lightMinute = "0" + lightMinute;
if(lightHour.length() == 1) lightHour = "0" + lightHour;
tvDateTimeSelected.setText(tinyDB.getString("timeStr"));
String darkMinute = String.valueOf(tinyDB.getInt("darkThemeTimeMinute"));
String darkHour = String.valueOf(tinyDB.getInt("darkThemeTimeHour"));
if(darkMinute.length() == 1) darkMinute = "0" + darkMinute;
if(darkHour.length() == 1) darkHour = "0" + darkHour;
activitySettingsAppearanceBinding.lightThemeSelectedTime.setText(ctx.getResources().getString(R.string.settingsThemeTimeSelectedHint, lightHour,
lightMinute));
activitySettingsAppearanceBinding.darkThemeSelectedTime.setText(ctx.getResources().getString(R.string.settingsThemeTimeSelectedHint, darkHour,
darkMinute));
activitySettingsAppearanceBinding.tvDateTimeSelected.setText(tinyDB.getString("timeStr"));
activitySettingsAppearanceBinding.customFontSelected.setText(tinyDB.getString("customFontStr", "Manrope"));
activitySettingsAppearanceBinding.themeSelected.setText(tinyDB.getString("themeStr", "Dark"));
if(tinyDB.getString("themeStr").startsWith("Auto")) {
darkTimeFrame.setVisibility(View.VISIBLE);
lightTimeFrame.setVisibility(View.VISIBLE);
}
else {
darkTimeFrame.setVisibility(View.GONE);
lightTimeFrame.setVisibility(View.GONE);
}
if(!tinyDB.getString("customFontStr").isEmpty()) {
customFontSelected.setText(tinyDB.getString("customFontStr"));
}
if(!tinyDB.getString("themeStr").isEmpty()) {
themeSelected.setText(tinyDB.getString("themeStr"));
}
if(timeSelectedChoice == 0) {
timeSelectedChoice = tinyDB.getInt("timeId");
}
if(customFontSelectedChoice == 0) {
customFontSelectedChoice = tinyDB.getInt("customFontId", 1);
}
if(themeSelectedChoice == 0) {
themeSelectedChoice = tinyDB.getInt("themeId");
}
timeSelectedChoice = tinyDB.getInt("timeId");
customFontSelectedChoice = tinyDB.getInt("customFontId", 1);
themeSelectedChoice = tinyDB.getInt("themeId");
counterBadgesSwitch.setChecked(tinyDB.getBoolean("enableCounterBadges"));
@ -105,7 +110,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, (dialogInterfaceTheme, i) -> {
themeSelectedChoice = i;
themeSelected.setText(themeList[i]);
activitySettingsAppearanceBinding.themeSelected.setText(themeList[i]);
tinyDB.putString("themeStr", themeList[i]);
tinyDB.putInt("themeId", i);
@ -120,6 +125,16 @@ public class SettingsAppearanceActivity extends BaseActivity {
cfDialog.show();
});
lightTimeFrame.setOnClickListener(view -> {
LightTimePicker timePicker = new LightTimePicker();
timePicker.show(getSupportFragmentManager(), "timePicker");
});
darkTimeFrame.setOnClickListener(view -> {
DarkTimePicker timePicker = new DarkTimePicker();
timePicker.show(getSupportFragmentManager(), "timePicker");
});
// custom font dialog
customFontFrame.setOnClickListener(view -> {
@ -131,7 +146,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, (dialogInterfaceCustomFont, i) -> {
customFontSelectedChoice = i;
customFontSelected.setText(customFontList[i]);
activitySettingsAppearanceBinding.customFontSelected.setText(customFontList[i]);
tinyDB.putString("customFontStr", customFontList[i]);
tinyDB.putInt("customFontId", i);
@ -157,7 +172,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, (dialogInterfaceTime, i) -> {
timeSelectedChoice = i;
tvDateTimeSelected.setText(timeList[i]);
activitySettingsAppearanceBinding.tvDateTimeSelected.setText(timeList[i]);
tinyDB.putString("timeStr", timeList[i]);
tinyDB.putInt("timeId", i);
@ -184,4 +199,54 @@ public class SettingsAppearanceActivity extends BaseActivity {
onClickListener = view -> finish();
}
public static class LightTimePicker extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
TinyDB db = TinyDB.getInstance(getContext());
@NotNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int hour = db.getInt("lightThemeTimeHour");
int minute = db.getInt("lightThemeTimeMinute");
return new TimePickerDialog(getActivity(), this, hour, minute, true);
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
db.putInt("lightThemeTimeHour", hourOfDay);
db.putInt("lightThemeTimeMinute", minute);
db.putBoolean("refreshParent", true);
requireActivity().overridePendingTransition(0, 0);
this.dismiss();
Toasty.success(requireActivity().getApplicationContext(), requireContext().getResources().getString(R.string.settingsSave));
requireActivity().recreate();
}
}
public static class DarkTimePicker extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
TinyDB db = TinyDB.getInstance(getContext());
@NotNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int hour = db.getInt("darkThemeTimeHour");
int minute = db.getInt("darkThemeTimeMinute");
return new TimePickerDialog(getActivity(), this, hour, minute, true);
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
db.putInt("darkThemeTimeHour", hourOfDay);
db.putInt("darkThemeTimeMinute", minute);
db.putBoolean("refreshParent", true);
requireActivity().overridePendingTransition(0, 0);
this.dismiss();
Toasty.success(requireActivity().getApplicationContext(), requireContext().getResources().getString(R.string.settingsSave));
requireActivity().recreate();
}
}
}

View File

@ -157,5 +157,15 @@ public class MainApplication extends Application {
tinyDB.putInt("langId", 0);
}
if(tinyDB.getInt("darkThemeTimeHour", 100) == 100) {
tinyDB.putInt("lightThemeTimeHour", 6);
tinyDB.putInt("lightThemeTimeMinute", 0);
tinyDB.putInt("darkThemeTimeHour", 18);
tinyDB.putInt("darkThemeTimeMinute", 0);
}
if(tinyDB.getString("timeStr").isEmpty()) {
tinyDB.putString("timeStr", getString(R.string.settingsDateTimeHeaderDefault));
}
}
}

View File

@ -69,17 +69,17 @@ public class TimeHelper {
}
public static boolean timeBetweenHours(int fromHour, int toHour) {
public static boolean timeBetweenHours(int fromHour, int toHour, int fromMinute, int toMinute) {
Calendar cal = Calendar.getInstance();
Calendar from = Calendar.getInstance();
from.set(Calendar.HOUR_OF_DAY, fromHour);
from.set(Calendar.MINUTE, 0);
from.set(Calendar.MINUTE, fromMinute);
Calendar to = Calendar.getInstance();
to.set(Calendar.HOUR_OF_DAY, toHour);
to.set(Calendar.MINUTE, 0);
to.set(Calendar.MINUTE, toMinute);
if(to.before(from)) {
if(cal.after(to)) {

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="1px" android:height="1px" />
<solid android:color="@color/toastBackground" />
</shape>

View File

@ -81,6 +81,72 @@
</LinearLayout>
<LinearLayout
android:id="@+id/lightThemeTimeSelectionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:focusable="true"
android:clickable="true"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/lightThemeTimeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="44dp"
android:layout_marginEnd="24dp"
android:text="@string/settingsLightThemeTimeSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp" />
<TextView
android:id="@+id/lightThemeSelectedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="44dp"
android:layout_marginEnd="24dp"
android:text="@string/settingsThemeTimeSelectedHint"
android:textColor="?attr/selectedTextColor"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/darkThemeTimeSelectionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:focusable="true"
android:clickable="true"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/darkThemeTimeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="44dp"
android:layout_marginEnd="24dp"
android:text="@string/settingsDarkThemeTimeSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp" />
<TextView
android:id="@+id/darkThemeSelectedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="44dp"
android:layout_marginEnd="24dp"
android:text="@string/settingsThemeTimeSelectedHint"
android:textColor="?attr/selectedTextColor"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/customFontFrame"
android:layout_width="match_parent"

View File

@ -235,6 +235,9 @@
<string name="settingsDateTimeHeaderDefault">Pretty</string>
<string name="settingsDateTimeNormal">Normal</string>
<string name="settingsLanguageSelectorDialogTitle">Choose Language</string>
<string name="settingsLightThemeTimeSelectorHeader">Light Theme Switch Time</string>
<string name="settingsDarkThemeTimeSelectorHeader">Dark Theme Switch Time</string>
<string name="settingsThemeTimeSelectedHint" translatable="false">%s:%s</string>
<string name="settingsTimeSelectorDialogTitle">Choose Time Format</string>
<string name="settingsHelpTranslateText">Translate GitNex via Crowdin</string>
<string name="codeBlockSelectedText" translatable="false">Green - Black</string>

View File

@ -2,7 +2,7 @@
<resources>
<!-- Dark theme - default -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<style name="AppTheme" parent="Theme.MaterialComponents.NoActionBar">
<item name="android:statusBarColor">@color/colorPrimary</item>
<item name="android:typeface">monospace</item>
<item name="colorAccent">@color/colorAccent</item>
@ -39,6 +39,7 @@
<item name="colorSurface">@color/inputBackground</item>
<item name="shapeAppearanceSmallComponent">@style/inputsMaterialComponentCorner</item>
<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
<item name="android:listDivider">@drawable/shape_list_divider</item>
</style>
<!-- Dark theme - default -->