mirror of
https://github.com/jahruz67/Bible-Daily.git
synced 2026-08-08 18:14:05 +00:00
Add dark mode support and improve language handling in SettingsActivity
- Refactored color constants to support both light and dark modes. - Implemented a toggle for dark mode in SettingsActivity. - Updated language selection functionality to correctly display "Español". - Enhanced prayer management in ExtrasActivity with a detailed view. - Added new styles for dark mode in styles.xml.
This commit is contained in:
@@ -0,0 +1,478 @@
|
||||
package com.bibliadiaria.app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class SettingsActivity extends Activity {
|
||||
// Light mode colors
|
||||
private static final int COLOR_BG_LIGHT = Color.rgb(247, 248, 246);
|
||||
private static final int COLOR_CARD_LIGHT = Color.WHITE;
|
||||
private static final int COLOR_INK_LIGHT = Color.rgb(25, 31, 31);
|
||||
private static final int COLOR_MUTED_LIGHT = Color.rgb(91, 99, 98);
|
||||
private static final int COLOR_STROKE_LIGHT = Color.rgb(219, 226, 222);
|
||||
private static final int COLOR_CARD_STROKE_LIGHT = Color.rgb(229, 232, 230);
|
||||
|
||||
// Dark mode colors
|
||||
private static final int COLOR_BG_DARK = Color.rgb(26, 28, 30);
|
||||
private static final int COLOR_CARD_DARK = Color.rgb(38, 41, 44);
|
||||
private static final int COLOR_INK_DARK = Color.rgb(224, 226, 219);
|
||||
private static final int COLOR_MUTED_DARK = Color.rgb(158, 163, 160);
|
||||
private static final int COLOR_STROKE_DARK = Color.rgb(48, 52, 55);
|
||||
private static final int COLOR_CARD_STROKE_DARK = Color.rgb(58, 62, 65);
|
||||
|
||||
private static final int COLOR_ACCENT = Color.rgb(0, 107, 90);
|
||||
private static final int COLOR_WARM = Color.rgb(217, 75, 61);
|
||||
|
||||
private ExecutorService executor;
|
||||
private TextView statusText;
|
||||
private TextView installedVersionText;
|
||||
private TextView checkButton;
|
||||
private TextView downloadButton;
|
||||
private TextView voiceSubtitleText;
|
||||
private TextView voiceButton;
|
||||
private UpdateManager.UpdateInfo latestInfo;
|
||||
private boolean isEnglish;
|
||||
private boolean isDarkMode;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
isEnglish = UpdateManager.isEnglish(this);
|
||||
isDarkMode = UpdateManager.isDarkMode(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(bg());
|
||||
getWindow().setNavigationBarColor(bg());
|
||||
}
|
||||
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
setContentView(createScreen());
|
||||
updateInstalledVersionText();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (executor != null) {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
}
|
||||
|
||||
private int bg() { return isDarkMode ? COLOR_BG_DARK : COLOR_BG_LIGHT; }
|
||||
private int card() { return isDarkMode ? COLOR_CARD_DARK : COLOR_CARD_LIGHT; }
|
||||
private int ink() { return isDarkMode ? COLOR_INK_DARK : COLOR_INK_LIGHT; }
|
||||
private int muted() { return isDarkMode ? COLOR_MUTED_DARK : COLOR_MUTED_LIGHT; }
|
||||
private int stroke() { return isDarkMode ? COLOR_STROKE_DARK : COLOR_STROKE_LIGHT; }
|
||||
private int cardStroke() { return isDarkMode ? COLOR_CARD_STROKE_DARK : COLOR_CARD_STROKE_LIGHT; }
|
||||
|
||||
private View createScreen() {
|
||||
FrameLayout root = new FrameLayout(this);
|
||||
root.setBackgroundColor(bg());
|
||||
|
||||
ScrollView scrollView = new ScrollView(this);
|
||||
scrollView.setFillViewport(true);
|
||||
scrollView.setClipToPadding(false);
|
||||
|
||||
LinearLayout content = new LinearLayout(this);
|
||||
content.setOrientation(LinearLayout.VERTICAL);
|
||||
content.setPadding(dp(20), dp(28), dp(20), dp(28));
|
||||
scrollView.addView(content, new ScrollView.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
content.addView(createTopBar());
|
||||
|
||||
TextView title = textView("Settings", 34, ink(), Typeface.BOLD);
|
||||
title.setIncludeFontPadding(false);
|
||||
LinearLayout.LayoutParams titleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
titleParams.setMargins(0, dp(18), 0, dp(18));
|
||||
content.addView(title, titleParams);
|
||||
|
||||
content.addView(createDarkModeCard());
|
||||
content.addView(createLanguageCard());
|
||||
content.addView(createVoiceCard());
|
||||
content.addView(createVersionCard());
|
||||
|
||||
checkButton = actionButton(isEnglish ? "Check now" : "Comprobar", COLOR_ACCENT, Color.WHITE);
|
||||
checkButton.setOnClickListener(view -> checkForUpdate());
|
||||
LinearLayout.LayoutParams checkParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
dp(46)
|
||||
);
|
||||
checkParams.setMargins(0, dp(16), 0, 0);
|
||||
content.addView(checkButton, checkParams);
|
||||
|
||||
downloadButton = actionButton("Download latest APK", COLOR_WARM, Color.WHITE);
|
||||
downloadButton.setVisibility(View.GONE);
|
||||
downloadButton.setOnClickListener(view -> {
|
||||
String url = latestInfo == null ? UpdateManager.APK_URL : latestInfo.apkUrl;
|
||||
UpdateManager.openDownload(this, url);
|
||||
});
|
||||
LinearLayout.LayoutParams downloadParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
dp(46)
|
||||
);
|
||||
downloadParams.setMargins(0, dp(10), 0, 0);
|
||||
content.addView(downloadButton, downloadParams);
|
||||
|
||||
root.addView(scrollView, new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
));
|
||||
|
||||
root.setOnApplyWindowInsetsListener((view, insets) -> {
|
||||
content.setPadding(
|
||||
dp(20),
|
||||
dp(28) + insets.getSystemWindowInsetTop(),
|
||||
dp(20),
|
||||
dp(28) + insets.getSystemWindowInsetBottom()
|
||||
);
|
||||
return insets;
|
||||
});
|
||||
root.requestApplyInsets();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private View createTopBar() {
|
||||
LinearLayout topBar = new LinearLayout(this);
|
||||
topBar.setOrientation(LinearLayout.HORIZONTAL);
|
||||
topBar.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
TextView label = textView("APP", 12, COLOR_ACCENT, Typeface.BOLD);
|
||||
topBar.addView(label, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
1f
|
||||
));
|
||||
|
||||
TextView back = textView(isEnglish ? "Extras" : "Extras", 15, COLOR_ACCENT, Typeface.BOLD);
|
||||
back.setGravity(Gravity.CENTER);
|
||||
back.setPadding(dp(14), 0, dp(14), 0);
|
||||
back.setBackground(roundedRect(card(), dp(8), stroke(), dp(1)));
|
||||
back.setOnClickListener(view -> finish());
|
||||
topBar.addView(back, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
dp(40)
|
||||
));
|
||||
|
||||
return topBar;
|
||||
}
|
||||
|
||||
private View createDarkModeCard() {
|
||||
LinearLayout card = createCard();
|
||||
card.setOrientation(LinearLayout.HORIZONTAL);
|
||||
card.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
LinearLayout copy = new LinearLayout(this);
|
||||
copy.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
TextView title = textView(isEnglish ? "Dark Mode" : "Modo oscuro", 20, ink(), Typeface.BOLD);
|
||||
title.setIncludeFontPadding(false);
|
||||
copy.addView(title);
|
||||
|
||||
TextView subtitle = textView(
|
||||
isEnglish ? "Use dark colors for the interface" : "Usar colores oscuros para la interfaz",
|
||||
14, muted(), Typeface.NORMAL);
|
||||
LinearLayout.LayoutParams subtitleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
subtitleParams.setMargins(0, dp(6), 0, 0);
|
||||
copy.addView(subtitle, subtitleParams);
|
||||
|
||||
card.addView(copy, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
1f
|
||||
));
|
||||
|
||||
final Switch darkToggle = new Switch(this);
|
||||
darkToggle.setChecked(isDarkMode);
|
||||
darkToggle.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
UpdateManager.setDarkMode(this, isChecked);
|
||||
isDarkMode = isChecked;
|
||||
recreate();
|
||||
});
|
||||
card.addView(darkToggle, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
private View createLanguageCard() {
|
||||
LinearLayout card = createCard();
|
||||
card.setOrientation(LinearLayout.HORIZONTAL);
|
||||
card.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
LinearLayout copy = new LinearLayout(this);
|
||||
copy.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
TextView title = textView("Language", 20, ink(), Typeface.BOLD);
|
||||
title.setIncludeFontPadding(false);
|
||||
copy.addView(title);
|
||||
|
||||
TextView subtitle = textView("Select the language for daily readings", 14, muted(), Typeface.NORMAL);
|
||||
LinearLayout.LayoutParams subtitleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
subtitleParams.setMargins(0, dp(6), 0, 0);
|
||||
copy.addView(subtitle, subtitleParams);
|
||||
|
||||
card.addView(copy, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
1f
|
||||
));
|
||||
|
||||
TextView langToggle = actionButton(UpdateManager.isEnglish(this) ? "English" : "Español", COLOR_ACCENT, Color.WHITE);
|
||||
langToggle.setOnClickListener(view -> {
|
||||
boolean current = UpdateManager.isEnglish(this);
|
||||
UpdateManager.setEnglish(this, !current);
|
||||
langToggle.setText(!current ? "English" : "Español");
|
||||
updateVoiceCard();
|
||||
});
|
||||
card.addView(langToggle, new LinearLayout.LayoutParams(dp(100), dp(40)));
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
private View createVoiceCard() {
|
||||
LinearLayout card = createCard();
|
||||
card.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
LinearLayout copy = new LinearLayout(this);
|
||||
copy.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
TextView title = textView("Voice", 20, ink(), Typeface.BOLD);
|
||||
title.setIncludeFontPadding(false);
|
||||
copy.addView(title);
|
||||
|
||||
voiceSubtitleText = textView("", 14, muted(), Typeface.NORMAL);
|
||||
LinearLayout.LayoutParams subtitleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
subtitleParams.setMargins(0, dp(6), 0, 0);
|
||||
copy.addView(voiceSubtitleText, subtitleParams);
|
||||
|
||||
card.addView(copy, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
voiceButton = actionButton("", COLOR_ACCENT, Color.WHITE);
|
||||
voiceButton.setOnClickListener(view -> showVoicePicker());
|
||||
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
dp(42)
|
||||
);
|
||||
buttonParams.setMargins(0, dp(12), 0, 0);
|
||||
card.addView(voiceButton, buttonParams);
|
||||
|
||||
updateVoiceCard();
|
||||
return card;
|
||||
}
|
||||
|
||||
private View createVersionCard() {
|
||||
LinearLayout card = createCard();
|
||||
card.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
TextView title = textView("Version", 20, ink(), Typeface.BOLD);
|
||||
title.setIncludeFontPadding(false);
|
||||
card.addView(title);
|
||||
|
||||
installedVersionText = textView("", 15, muted(), Typeface.BOLD);
|
||||
LinearLayout.LayoutParams installedParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
installedParams.setMargins(0, dp(10), 0, 0);
|
||||
card.addView(installedVersionText, installedParams);
|
||||
|
||||
statusText = textView("Ready to check for updates.", 15, muted(), Typeface.NORMAL);
|
||||
statusText.setLineSpacing(dp(3), 1.1f);
|
||||
LinearLayout.LayoutParams statusParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
statusParams.setMargins(0, dp(8), 0, 0);
|
||||
card.addView(statusText, statusParams);
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
private void checkForUpdate() {
|
||||
if (executor == null || executor.isShutdown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
latestInfo = null;
|
||||
downloadButton.setVisibility(View.GONE);
|
||||
checkButton.setEnabled(false);
|
||||
checkButton.setAlpha(0.62f);
|
||||
statusText.setText("Checking for updates...");
|
||||
|
||||
executor.submit(() -> {
|
||||
try {
|
||||
UpdateManager.UpdateInfo info = UpdateManager.fetchLatestUpdate(this);
|
||||
runOnUiThread(() -> showUpdateResult(info));
|
||||
} catch (Exception error) {
|
||||
runOnUiThread(() -> showUpdateError(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showUpdateResult(UpdateManager.UpdateInfo info) {
|
||||
latestInfo = info;
|
||||
checkButton.setEnabled(true);
|
||||
checkButton.setAlpha(1f);
|
||||
|
||||
if (info.updateAvailable) {
|
||||
String version = info.latestVersionName.isEmpty()
|
||||
? String.valueOf(info.latestVersionCode)
|
||||
: info.latestVersionName + " (" + info.latestVersionCode + ")";
|
||||
statusText.setText("Update available: " + version);
|
||||
downloadButton.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
}
|
||||
|
||||
statusText.setText("You are on the latest build: "
|
||||
+ info.currentVersionName + " (" + info.currentVersionCode + ")");
|
||||
}
|
||||
|
||||
private void showUpdateError(Exception error) {
|
||||
checkButton.setEnabled(true);
|
||||
checkButton.setAlpha(1f);
|
||||
statusText.setText("Could not check for updates. " + cleanMessage(error));
|
||||
}
|
||||
|
||||
private void showVoicePicker() {
|
||||
boolean english = UpdateManager.isEnglish(this);
|
||||
UpdateManager.VoiceOption[] options = UpdateManager.getTtsVoiceOptions(english);
|
||||
String[] labels = new String[options.length];
|
||||
for (int index = 0; index < options.length; index++) {
|
||||
labels[index] = options[index].label;
|
||||
}
|
||||
|
||||
int selectedIndex = UpdateManager.getTtsVoiceIndex(
|
||||
english,
|
||||
UpdateManager.getTtsVoice(this, english)
|
||||
);
|
||||
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(english ? "English voice" : "Spanish voice")
|
||||
.setSingleChoiceItems(labels, selectedIndex, (dialog, which) -> {
|
||||
UpdateManager.setTtsVoice(this, english, options[which].id);
|
||||
updateVoiceCard();
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton("Cancel", null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void updateVoiceCard() {
|
||||
if (voiceSubtitleText == null || voiceButton == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean english = UpdateManager.isEnglish(this);
|
||||
String voiceId = UpdateManager.getTtsVoice(this, english);
|
||||
voiceSubtitleText.setText(english
|
||||
? "English voices are shown while English is selected"
|
||||
: "Las voces en español se muestran mientras el español esté seleccionado");
|
||||
voiceButton.setText(UpdateManager.getTtsVoiceLabel(english, voiceId));
|
||||
}
|
||||
|
||||
private void updateInstalledVersionText() {
|
||||
try {
|
||||
installedVersionText.setText(
|
||||
(isEnglish ? "Installed: " : "Instalada: ")
|
||||
+ UpdateManager.getInstalledVersionName(this)
|
||||
+ " (" + UpdateManager.getInstalledVersionCode(this) + ")");
|
||||
} catch (Exception error) {
|
||||
installedVersionText.setText(isEnglish ? "Installed version unavailable." : "Versión instalada no disponible.");
|
||||
}
|
||||
}
|
||||
|
||||
private String cleanMessage(Exception error) {
|
||||
String message = error.getMessage();
|
||||
if (message == null || message.trim().isEmpty()) {
|
||||
return "Unknown error.";
|
||||
}
|
||||
return message.trim();
|
||||
}
|
||||
|
||||
private LinearLayout createCard() {
|
||||
LinearLayout card = new LinearLayout(this);
|
||||
card.setPadding(dp(18), dp(16), dp(18), dp(16));
|
||||
card.setBackground(roundedRect(card(), dp(8), cardStroke(), dp(1)));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
card.setElevation(dp(1));
|
||||
}
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
params.setMargins(0, 0, 0, dp(14));
|
||||
card.setLayoutParams(params);
|
||||
return card;
|
||||
}
|
||||
|
||||
private TextView actionButton(String text, int backgroundColor, int textColor) {
|
||||
TextView button = textView(text, 15, textColor, Typeface.BOLD);
|
||||
button.setGravity(Gravity.CENTER);
|
||||
button.setPadding(dp(14), 0, dp(14), 0);
|
||||
button.setBackground(roundedRect(backgroundColor, dp(8), Color.TRANSPARENT, 0));
|
||||
return button;
|
||||
}
|
||||
|
||||
private TextView textView(String text, int sizeSp, int color, int style) {
|
||||
TextView textView = new TextView(this);
|
||||
textView.setText(text);
|
||||
textView.setTextSize(sizeSp);
|
||||
textView.setTextColor(color);
|
||||
textView.setTypeface(Typeface.DEFAULT, style);
|
||||
return textView;
|
||||
}
|
||||
|
||||
private GradientDrawable roundedRect(int color, int radius, int strokeColor, int strokeWidth) {
|
||||
GradientDrawable drawable = new GradientDrawable();
|
||||
drawable.setShape(GradientDrawable.RECTANGLE);
|
||||
drawable.setColor(color);
|
||||
drawable.setCornerRadius(radius);
|
||||
if (strokeWidth > 0) {
|
||||
drawable.setStroke(strokeWidth, strokeColor);
|
||||
}
|
||||
return drawable;
|
||||
}
|
||||
|
||||
private int dp(int value) {
|
||||
return Math.round(value * getResources().getDisplayMetrics().density);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
package com.bibliadiaria.app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class ExtrasActivity extends Activity {
|
||||
// Light mode colors
|
||||
private static final int COLOR_BG_LIGHT = Color.rgb(247, 248, 246);
|
||||
private static final int COLOR_CARD_LIGHT = Color.WHITE;
|
||||
private static final int COLOR_INK_LIGHT = Color.rgb(25, 31, 31);
|
||||
private static final int COLOR_MUTED_LIGHT = Color.rgb(91, 99, 98);
|
||||
private static final int COLOR_STROKE_LIGHT = Color.rgb(219, 226, 222);
|
||||
private static final int COLOR_CARD_STROKE_LIGHT = Color.rgb(229, 232, 230);
|
||||
|
||||
// Dark mode colors
|
||||
private static final int COLOR_BG_DARK = Color.rgb(26, 28, 30);
|
||||
private static final int COLOR_CARD_DARK = Color.rgb(38, 41, 44);
|
||||
private static final int COLOR_INK_DARK = Color.rgb(224, 226, 219);
|
||||
private static final int COLOR_MUTED_DARK = Color.rgb(158, 163, 160);
|
||||
private static final int COLOR_STROKE_DARK = Color.rgb(48, 52, 55);
|
||||
private static final int COLOR_CARD_STROKE_DARK = Color.rgb(58, 62, 65);
|
||||
|
||||
private static final int COLOR_ACCENT = Color.rgb(0, 107, 90);
|
||||
private static final int COLOR_WARM = Color.rgb(217, 75, 61);
|
||||
|
||||
private boolean isEnglish;
|
||||
private boolean isDarkMode;
|
||||
|
||||
private static final String VENI_CREATOR_PRAYER =
|
||||
"Ven, Esp\u00edritu Creador,\n"
|
||||
+ "visita las almas de tus fieles\n"
|
||||
+ "y llena de la gracia divina\n"
|
||||
+ "los corazones que t\u00fa mismo creaste.\n\n"
|
||||
+ "T\u00fa eres nuestro Consolador,\n"
|
||||
+ "don del Dios alt\u00edsimo,\n"
|
||||
+ "fuente viva, fuego, caridad\n"
|
||||
+ "y espiritual unci\u00f3n.\n\n"
|
||||
+ "T\u00fa derramas sobre nosotros\n"
|
||||
+ "los siete dones;\n"
|
||||
+ "t\u00fa eres el dedo de la diestra del Padre,\n"
|
||||
+ "promesa solemne del Padre,\n"
|
||||
+ "que pones en nuestros labios la palabra.\n\n"
|
||||
+ "Enciende tu luz en nuestras mentes,\n"
|
||||
+ "infunde tu amor en nuestros corazones\n"
|
||||
+ "y fortalece con tu fuerza constante\n"
|
||||
+ "la debilidad de nuestro cuerpo.\n\n"
|
||||
+ "Aleja de nosotros al enemigo,\n"
|
||||
+ "danos pronto la paz;\n"
|
||||
+ "siendo t\u00fa nuestro gu\u00eda,\n"
|
||||
+ "evitaremos todo mal.\n\n"
|
||||
+ "Por ti conozcamos al Padre,\n"
|
||||
+ "y tambi\u00e9n al Hijo;\n"
|
||||
+ "y que en ti, Esp\u00edritu de ambos,\n"
|
||||
+ "creamos en todo tiempo.\n\n"
|
||||
+ "Gloria a Dios Padre,\n"
|
||||
+ "y al Hijo que resucit\u00f3,\n"
|
||||
+ "y al Esp\u00edritu Consolador,\n"
|
||||
+ "por los siglos de los siglos.\n\n"
|
||||
+ "Am\u00e9n.";
|
||||
|
||||
private static final String ANGELUS_PRAYER =
|
||||
"El \u00c1ngel del Se\u00f1or anunci\u00f3 a Mar\u00eda.\n"
|
||||
+ "Y concibi\u00f3 por obra y gracia del Esp\u00edritu Santo.\n\n"
|
||||
+ "Dios te salve, Mar\u00eda, llena eres de gracia,\n"
|
||||
+ "el Se\u00f1or es contigo.\n"
|
||||
+ "Bendita t\u00fa eres entre todas las mujeres,\n"
|
||||
+ "y bendito es el fruto de tu vientre, Jes\u00fas.\n"
|
||||
+ "Santa Mar\u00eda, Madre de Dios,\n"
|
||||
+ "ruega por nosotros, pecadores,\n"
|
||||
+ "ahora y en la hora de nuestra muerte.\n"
|
||||
+ "Am\u00e9n.\n\n"
|
||||
+ "He aqu\u00ed la esclava del Se\u00f1or.\n"
|
||||
+ "H\u00e1gase en m\u00ed seg\u00fan tu palabra.\n\n"
|
||||
+ "Dios te salve, Mar\u00eda...\n\n"
|
||||
+ "Y el Verbo se hizo carne.\n"
|
||||
+ "Y habit\u00f3 entre nosotros.\n\n"
|
||||
+ "Dios te salve, Mar\u00eda...\n\n"
|
||||
+ "Ruega por nosotros, Santa Madre de Dios.\n"
|
||||
+ "Para que seamos dignos de alcanzar las promesas de Cristo.\n\n"
|
||||
+ "Infunde, Se\u00f1or, tu gracia en nuestros corazones,\n"
|
||||
+ "para que quienes hemos conocido por el anuncio del \u00c1ngel\n"
|
||||
+ "la encarnaci\u00f3n de tu Hijo Jesucristo,\n"
|
||||
+ "por su pasi\u00f3n y cruz seamos llevados\n"
|
||||
+ "a la gloria de su resurrecci\u00f3n.\n"
|
||||
+ "Por Jesucristo nuestro Se\u00f1or.\n\n"
|
||||
+ "Am\u00e9n.";
|
||||
|
||||
private static final String SALVE_REGINA_PRAYER =
|
||||
"Dios te salve, Reina y Madre de misericordia,\n"
|
||||
+ "vida, dulzura y esperanza nuestra;\n"
|
||||
+ "Dios te salve.\n\n"
|
||||
+ "A ti llamamos los desterrados hijos de Eva;\n"
|
||||
+ "a ti suspiramos, gimiendo y llorando\n"
|
||||
+ "en este valle de l\u00e1grimas.\n\n"
|
||||
+ "Ea, pues, Se\u00f1ora, abogada nuestra,\n"
|
||||
+ "vuelve a nosotros esos tus ojos misericordiosos;\n"
|
||||
+ "y despu\u00e9s de este destierro,\n"
|
||||
+ "mu\u00e9stranos a Jes\u00fas,\n"
|
||||
+ "fruto bendito de tu vientre.\n\n"
|
||||
+ "\u00a1Oh clemente, oh piadosa,\n"
|
||||
+ "oh dulce Virgen Mar\u00eda!\n\n"
|
||||
+ "Ruega por nosotros, Santa Madre de Dios,\n"
|
||||
+ "para que seamos dignos de alcanzar\n"
|
||||
+ "las promesas de nuestro Se\u00f1or Jesucristo.\n\n"
|
||||
+ "Am\u00e9n.";
|
||||
|
||||
private static final String MEMORARE_PRAYER =
|
||||
"Acordaos, oh piados\u00edsima Virgen Mar\u00eda,\n"
|
||||
+ "que jam\u00e1s se ha o\u00eddo decir\n"
|
||||
+ "que ninguno de los que han acudido a vuestra protecci\u00f3n,\n"
|
||||
+ "implorado vuestra asistencia\n"
|
||||
+ "y reclamado vuestro socorro,\n"
|
||||
+ "haya sido abandonado de vos.\n\n"
|
||||
+ "Animado con esta confianza,\n"
|
||||
+ "a vos tambi\u00e9n acudo,\n"
|
||||
+ "oh Madre, Virgen de las v\u00edrgenes;\n"
|
||||
+ "y aunque gimiendo bajo el peso de mis pecados,\n"
|
||||
+ "me atrevo a comparecer ante vuestra presencia soberana.\n\n"
|
||||
+ "No desech\u00e9is, oh Madre de Dios,\n"
|
||||
+ "mis humildes s\u00faplicas;\n"
|
||||
+ "antes bien, escuchadlas y acogedlas benignamente.\n\n"
|
||||
+ "Am\u00e9n.";
|
||||
|
||||
private static final PrayerItem[] PRAYERS = {
|
||||
new PrayerItem("Ven, Esp\u00edritu Creador", "Veni Creator Spiritus", VENI_CREATOR_PRAYER),
|
||||
new PrayerItem("\u00c1ngelus", "Oraci\u00f3n de la Encarnaci\u00f3n", ANGELUS_PRAYER),
|
||||
new PrayerItem("Salve Regina", "Dios te salve, Reina", SALVE_REGINA_PRAYER),
|
||||
new PrayerItem("Acordaos", "Memorare", MEMORARE_PRAYER)
|
||||
};
|
||||
|
||||
private ScrollView scrollView;
|
||||
private LinearLayout listContainer;
|
||||
private LinearLayout detailContainer;
|
||||
private TextView titleText;
|
||||
private PrayerItem selectedPrayer = PRAYERS[0];
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
isEnglish = UpdateManager.isEnglish(this);
|
||||
isDarkMode = UpdateManager.isDarkMode(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(bg());
|
||||
getWindow().setNavigationBarColor(bg());
|
||||
}
|
||||
|
||||
setContentView(createScreen());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
boolean currentLanguage = UpdateManager.isEnglish(this);
|
||||
boolean currentDark = UpdateManager.isDarkMode(this);
|
||||
if (currentLanguage != isEnglish || currentDark != isDarkMode) {
|
||||
isEnglish = currentLanguage;
|
||||
isDarkMode = currentDark;
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (detailContainer != null && detailContainer.getVisibility() == View.VISIBLE) {
|
||||
showPrayerList();
|
||||
return;
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
private int bg() { return isDarkMode ? COLOR_BG_DARK : COLOR_BG_LIGHT; }
|
||||
private int card() { return isDarkMode ? COLOR_CARD_DARK : COLOR_CARD_LIGHT; }
|
||||
private int ink() { return isDarkMode ? COLOR_INK_DARK : COLOR_INK_LIGHT; }
|
||||
private int muted() { return isDarkMode ? COLOR_MUTED_DARK : COLOR_MUTED_LIGHT; }
|
||||
private int stroke() { return isDarkMode ? COLOR_STROKE_DARK : COLOR_STROKE_LIGHT; }
|
||||
private int cardStroke() { return isDarkMode ? COLOR_CARD_STROKE_DARK : COLOR_CARD_STROKE_LIGHT; }
|
||||
|
||||
private View createScreen() {
|
||||
FrameLayout root = new FrameLayout(this);
|
||||
root.setBackgroundColor(bg());
|
||||
|
||||
scrollView = new ScrollView(this);
|
||||
scrollView.setFillViewport(true);
|
||||
scrollView.setClipToPadding(false);
|
||||
|
||||
LinearLayout content = new LinearLayout(this);
|
||||
content.setOrientation(LinearLayout.VERTICAL);
|
||||
content.setPadding(dp(20), dp(28), dp(20), dp(28));
|
||||
scrollView.addView(content, new ScrollView.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
content.addView(createTopBar());
|
||||
|
||||
titleText = textView(isEnglish ? "Extras" : "Extras", 34, ink(), Typeface.BOLD);
|
||||
titleText.setIncludeFontPadding(false);
|
||||
LinearLayout.LayoutParams titleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
titleParams.setMargins(0, dp(18), 0, dp(18));
|
||||
content.addView(titleText, titleParams);
|
||||
|
||||
listContainer = new LinearLayout(this);
|
||||
listContainer.setOrientation(LinearLayout.VERTICAL);
|
||||
for (PrayerItem prayer : PRAYERS) {
|
||||
listContainer.addView(createPrayerCard(prayer));
|
||||
}
|
||||
content.addView(listContainer, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
detailContainer = new LinearLayout(this);
|
||||
detailContainer.setOrientation(LinearLayout.VERTICAL);
|
||||
detailContainer.setVisibility(View.GONE);
|
||||
content.addView(detailContainer, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
root.addView(scrollView, new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
));
|
||||
|
||||
root.setOnApplyWindowInsetsListener((view, insets) -> {
|
||||
content.setPadding(
|
||||
dp(20),
|
||||
dp(28) + insets.getSystemWindowInsetTop(),
|
||||
dp(20),
|
||||
dp(28) + insets.getSystemWindowInsetBottom()
|
||||
);
|
||||
return insets;
|
||||
});
|
||||
root.requestApplyInsets();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private View createTopBar() {
|
||||
LinearLayout topBar = new LinearLayout(this);
|
||||
topBar.setOrientation(LinearLayout.HORIZONTAL);
|
||||
topBar.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
TextView label = textView(isEnglish ? "PRAYERS" : "ORACIONES", 12, COLOR_ACCENT, Typeface.BOLD);
|
||||
topBar.addView(label, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
1f
|
||||
));
|
||||
|
||||
TextView settings = textView(isEnglish ? "Settings" : "Ajustes", 15, COLOR_ACCENT, Typeface.BOLD);
|
||||
settings.setGravity(Gravity.CENTER);
|
||||
settings.setPadding(dp(14), 0, dp(14), 0);
|
||||
settings.setBackground(roundedRect(card(), dp(8), stroke(), dp(1)));
|
||||
settings.setOnClickListener(view -> startActivity(new Intent(this, SettingsActivity.class)));
|
||||
LinearLayout.LayoutParams settingsParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
dp(40)
|
||||
);
|
||||
settingsParams.setMargins(0, 0, dp(8), 0);
|
||||
topBar.addView(settings, settingsParams);
|
||||
|
||||
TextView home = textView(isEnglish ? "Home" : "Inicio", 15, COLOR_ACCENT, Typeface.BOLD);
|
||||
home.setGravity(Gravity.CENTER);
|
||||
home.setPadding(dp(14), 0, dp(14), 0);
|
||||
home.setBackground(roundedRect(card(), dp(8), stroke(), dp(1)));
|
||||
home.setOnClickListener(view -> finish());
|
||||
topBar.addView(home, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
dp(40)
|
||||
));
|
||||
|
||||
return topBar;
|
||||
}
|
||||
|
||||
private View createPrayerCard(PrayerItem prayer) {
|
||||
LinearLayout card = new LinearLayout(this);
|
||||
card.setOrientation(LinearLayout.HORIZONTAL);
|
||||
card.setGravity(Gravity.CENTER_VERTICAL);
|
||||
card.setPadding(dp(18), dp(16), dp(16), dp(16));
|
||||
card.setBackground(roundedRect(card(), dp(8), cardStroke(), dp(1)));
|
||||
card.setOnClickListener(view -> showPrayerDetail(prayer));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
card.setElevation(dp(1));
|
||||
}
|
||||
|
||||
LinearLayout copy = new LinearLayout(this);
|
||||
copy.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
TextView title = textView(prayer.title, 20, ink(), Typeface.BOLD);
|
||||
title.setIncludeFontPadding(false);
|
||||
copy.addView(title);
|
||||
|
||||
TextView subtitle = textView(prayer.subtitle, 14, muted(), Typeface.BOLD);
|
||||
LinearLayout.LayoutParams subtitleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
subtitleParams.setMargins(0, dp(6), 0, 0);
|
||||
copy.addView(subtitle, subtitleParams);
|
||||
|
||||
card.addView(copy, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
1f
|
||||
));
|
||||
|
||||
TextView arrow = textView(">", 22, COLOR_ACCENT, Typeface.BOLD);
|
||||
arrow.setGravity(Gravity.CENTER);
|
||||
card.addView(arrow, new LinearLayout.LayoutParams(
|
||||
dp(28),
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
LinearLayout.LayoutParams cardParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
cardParams.setMargins(0, 0, 0, dp(12));
|
||||
card.setLayoutParams(cardParams);
|
||||
return card;
|
||||
}
|
||||
|
||||
private void renderPrayerDetail() {
|
||||
detailContainer.removeAllViews();
|
||||
|
||||
TextView subtitle = textView(selectedPrayer.subtitle, 14, COLOR_WARM, Typeface.BOLD);
|
||||
detailContainer.addView(subtitle);
|
||||
|
||||
TextView prayer = textView(selectedPrayer.body, 21, ink(), Typeface.NORMAL);
|
||||
prayer.setLineSpacing(dp(5), 1.14f);
|
||||
LinearLayout.LayoutParams prayerParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
prayerParams.setMargins(0, dp(16), 0, dp(18));
|
||||
detailContainer.addView(prayer, prayerParams);
|
||||
|
||||
TextView backToList = textView(isEnglish ? "Back to extras" : "Volver a extras", 15, COLOR_ACCENT, Typeface.BOLD);
|
||||
backToList.setGravity(Gravity.CENTER);
|
||||
backToList.setPadding(dp(14), 0, dp(14), 0);
|
||||
backToList.setBackground(roundedRect(card(), dp(8), stroke(), dp(1)));
|
||||
backToList.setOnClickListener(view -> showPrayerList());
|
||||
detailContainer.addView(backToList, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
dp(42)
|
||||
));
|
||||
}
|
||||
|
||||
private void showPrayerDetail(PrayerItem prayer) {
|
||||
selectedPrayer = prayer;
|
||||
titleText.setText(prayer.title);
|
||||
renderPrayerDetail();
|
||||
listContainer.setVisibility(View.GONE);
|
||||
detailContainer.setVisibility(View.VISIBLE);
|
||||
scrollToTop();
|
||||
}
|
||||
|
||||
private void showPrayerList() {
|
||||
titleText.setText(isEnglish ? "Extras" : "Extras");
|
||||
detailContainer.setVisibility(View.GONE);
|
||||
listContainer.setVisibility(View.VISIBLE);
|
||||
scrollToTop();
|
||||
}
|
||||
|
||||
private void scrollToTop() {
|
||||
if (scrollView != null) {
|
||||
scrollView.post(() -> scrollView.smoothScrollTo(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
private TextView textView(String text, int sizeSp, int color, int style) {
|
||||
TextView textView = new TextView(this);
|
||||
textView.setText(text);
|
||||
textView.setTextSize(sizeSp);
|
||||
textView.setTextColor(color);
|
||||
textView.setTypeface(Typeface.DEFAULT, style);
|
||||
return textView;
|
||||
}
|
||||
|
||||
private GradientDrawable roundedRect(int color, int radius, int strokeColor, int strokeWidth) {
|
||||
GradientDrawable drawable = new GradientDrawable();
|
||||
drawable.setShape(GradientDrawable.RECTANGLE);
|
||||
drawable.setColor(color);
|
||||
drawable.setCornerRadius(radius);
|
||||
if (strokeWidth > 0) {
|
||||
drawable.setStroke(strokeWidth, strokeColor);
|
||||
}
|
||||
return drawable;
|
||||
}
|
||||
|
||||
private int dp(int value) {
|
||||
return Math.round(value * getResources().getDisplayMetrics().density);
|
||||
}
|
||||
|
||||
private static class PrayerItem {
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final String body;
|
||||
|
||||
PrayerItem(String title, String subtitle, String body) {
|
||||
this.title = title;
|
||||
this.subtitle = subtitle;
|
||||
this.body = body;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,10 +50,29 @@ import java.util.concurrent.Executors;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
private static final int COLOR_BACKGROUND = Color.rgb(247, 248, 246);
|
||||
private static final int COLOR_CARD = Color.WHITE;
|
||||
private static final int COLOR_INK = Color.rgb(25, 31, 31);
|
||||
private static final int COLOR_MUTED = Color.rgb(91, 99, 98);
|
||||
// Light mode colors
|
||||
private static final int COLOR_BACKGROUND_LIGHT = Color.rgb(247, 248, 246);
|
||||
private static final int COLOR_CARD_LIGHT = Color.WHITE;
|
||||
private static final int COLOR_INK_LIGHT = Color.rgb(25, 31, 31);
|
||||
private static final int COLOR_MUTED_LIGHT = Color.rgb(91, 99, 98);
|
||||
private static final int COLOR_STROKE_LIGHT = Color.rgb(229, 232, 230);
|
||||
private static final int COLOR_CHIP_BG_LIGHT = Color.rgb(219, 226, 222);
|
||||
private static final int COLOR_SPEAKER_BG_LIGHT = Color.rgb(229, 244, 240);
|
||||
private static final int COLOR_REFERENCE_BG_LIGHT = Color.rgb(229, 244, 240);
|
||||
private static final int COLOR_TODAY_BG_LIGHT = Color.rgb(255, 239, 236);
|
||||
|
||||
// Dark mode colors
|
||||
private static final int COLOR_BACKGROUND_DARK = Color.rgb(26, 28, 30);
|
||||
private static final int COLOR_CARD_DARK = Color.rgb(38, 41, 44);
|
||||
private static final int COLOR_INK_DARK = Color.rgb(224, 226, 219);
|
||||
private static final int COLOR_MUTED_DARK = Color.rgb(158, 163, 160);
|
||||
private static final int COLOR_STROKE_DARK = Color.rgb(58, 62, 65);
|
||||
private static final int COLOR_CHIP_BG_DARK = Color.rgb(48, 52, 55);
|
||||
private static final int COLOR_SPEAKER_BG_DARK = Color.rgb(45, 65, 60);
|
||||
private static final int COLOR_REFERENCE_BG_DARK = Color.rgb(45, 65, 60);
|
||||
private static final int COLOR_TODAY_BG_DARK = Color.rgb(75, 50, 48);
|
||||
|
||||
// Shared colors (no change between modes)
|
||||
private static final int COLOR_ACCENT = Color.rgb(0, 107, 90);
|
||||
private static final int COLOR_WARM = Color.rgb(217, 75, 61);
|
||||
private static final int COLOR_HOLIDAY_BG = Color.rgb(255, 246, 229);
|
||||
@@ -120,19 +139,21 @@ public class MainActivity extends Activity {
|
||||
private int ttsGeneration;
|
||||
private float readingFontSp;
|
||||
private boolean isEnglish;
|
||||
private boolean isDarkMode;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(COLOR_BACKGROUND);
|
||||
getWindow().setNavigationBarColor(COLOR_BACKGROUND);
|
||||
getWindow().setStatusBarColor(bg());
|
||||
getWindow().setNavigationBarColor(bg());
|
||||
}
|
||||
|
||||
preferences = getSharedPreferences("preferencias_lectura", MODE_PRIVATE);
|
||||
readingFontSp = preferences.getFloat("tamano_letra", 20f);
|
||||
isEnglish = preferences.getBoolean("is_english", false);
|
||||
isDarkMode = preferences.getBoolean("dark_mode", false);
|
||||
selectedDateCalendar = startOfDay(Calendar.getInstance());
|
||||
visibleMonthCalendar = startOfMonth(selectedDateCalendar);
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
@@ -163,15 +184,28 @@ public class MainActivity extends Activity {
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
boolean currentLanguage = UpdateManager.isEnglish(this);
|
||||
if (currentLanguage != isEnglish) {
|
||||
boolean currentDark = UpdateManager.isDarkMode(this);
|
||||
if (currentLanguage != isEnglish || currentDark != isDarkMode) {
|
||||
isEnglish = currentLanguage;
|
||||
isDarkMode = currentDark;
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Dark mode aware color helpers ---
|
||||
private int bg() { return isDarkMode ? COLOR_BACKGROUND_DARK : COLOR_BACKGROUND_LIGHT; }
|
||||
private int card() { return isDarkMode ? COLOR_CARD_DARK : COLOR_CARD_LIGHT; }
|
||||
private int ink() { return isDarkMode ? COLOR_INK_DARK : COLOR_INK_LIGHT; }
|
||||
private int muted() { return isDarkMode ? COLOR_MUTED_DARK : COLOR_MUTED_LIGHT; }
|
||||
private int stroke() { return isDarkMode ? COLOR_STROKE_DARK : COLOR_STROKE_LIGHT; }
|
||||
private int chipBg() { return isDarkMode ? COLOR_CHIP_BG_DARK : COLOR_CHIP_BG_LIGHT; }
|
||||
private int speakerBg() { return isDarkMode ? COLOR_SPEAKER_BG_DARK : COLOR_SPEAKER_BG_LIGHT; }
|
||||
private int referenceBg() { return isDarkMode ? COLOR_REFERENCE_BG_DARK : COLOR_REFERENCE_BG_LIGHT; }
|
||||
private int todayBg() { return isDarkMode ? COLOR_TODAY_BG_DARK : COLOR_TODAY_BG_LIGHT; }
|
||||
|
||||
private View createScreen() {
|
||||
FrameLayout root = new FrameLayout(this);
|
||||
root.setBackgroundColor(COLOR_BACKGROUND);
|
||||
root.setBackgroundColor(bg());
|
||||
|
||||
ScrollView scrollView = new ScrollView(this);
|
||||
scrollView.setFillViewport(true);
|
||||
@@ -195,7 +229,7 @@ public class MainActivity extends Activity {
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
sourceText = textView(isEnglish ? "Source: Vatican News" : "Fuente: Vatican News", 13, COLOR_MUTED, Typeface.NORMAL);
|
||||
sourceText = textView(isEnglish ? "Source: Vatican News" : "Fuente: Vatican News", 13, muted(), Typeface.NORMAL);
|
||||
LinearLayout.LayoutParams sourceParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
@@ -268,7 +302,7 @@ public class MainActivity extends Activity {
|
||||
topRow.addView(createDateChip());
|
||||
header.addView(topRow);
|
||||
|
||||
TextView title = textView(isEnglish ? "Word of the day" : "Palabra del día", 34, COLOR_INK, Typeface.BOLD);
|
||||
TextView title = textView(isEnglish ? "Word of the day" : "Palabra del día", 34, ink(), Typeface.BOLD);
|
||||
title.setIncludeFontPadding(false);
|
||||
LinearLayout.LayoutParams titleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
@@ -292,7 +326,7 @@ public class MainActivity extends Activity {
|
||||
calendarParams.setMargins(0, dp(2), 0, dp(14));
|
||||
header.addView(calendarPanel, calendarParams);
|
||||
|
||||
dateText = textView("", 16, COLOR_MUTED, Typeface.BOLD);
|
||||
dateText = textView("", 16, muted(), Typeface.BOLD);
|
||||
header.addView(dateText);
|
||||
|
||||
holidayTagsRow = new LinearLayout(this);
|
||||
@@ -306,7 +340,7 @@ public class MainActivity extends Activity {
|
||||
tagsParams.setMargins(0, dp(8), 0, 0);
|
||||
header.addView(holidayTagsRow, tagsParams);
|
||||
|
||||
liturgyText = textView("", 16, COLOR_INK, Typeface.NORMAL);
|
||||
liturgyText = textView("", 16, ink(), Typeface.NORMAL);
|
||||
liturgyText.setLineSpacing(0, 1.12f);
|
||||
LinearLayout.LayoutParams liturgyParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
@@ -339,7 +373,7 @@ public class MainActivity extends Activity {
|
||||
chip.setOrientation(LinearLayout.HORIZONTAL);
|
||||
chip.setGravity(Gravity.CENTER_VERTICAL);
|
||||
chip.setPadding(dp(12), dp(8), dp(10), dp(8));
|
||||
chip.setBackground(roundedRect(Color.WHITE, dp(8), Color.rgb(219, 226, 222), dp(1)));
|
||||
chip.setBackground(roundedRect(card(), dp(8), chipBg(), dp(1)));
|
||||
chip.setContentDescription(isEnglish ? "Choose date" : "Elegir fecha");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
chip.setElevation(dp(1));
|
||||
@@ -350,11 +384,11 @@ public class MainActivity extends Activity {
|
||||
labelGroup.setOrientation(LinearLayout.VERTICAL);
|
||||
labelGroup.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
dateChipPrimary = textView("", 20, COLOR_INK, Typeface.BOLD);
|
||||
dateChipPrimary = textView("", 20, ink(), Typeface.BOLD);
|
||||
dateChipPrimary.setIncludeFontPadding(false);
|
||||
labelGroup.addView(dateChipPrimary);
|
||||
|
||||
dateChipSecondary = textView("", 11, COLOR_MUTED, Typeface.BOLD);
|
||||
dateChipSecondary = textView("", 11, muted(), Typeface.BOLD);
|
||||
dateChipSecondary.setIncludeFontPadding(false);
|
||||
labelGroup.addView(dateChipSecondary);
|
||||
|
||||
@@ -378,7 +412,7 @@ public class MainActivity extends Activity {
|
||||
panel.setOrientation(LinearLayout.VERTICAL);
|
||||
panel.setPadding(dp(14), dp(12), dp(14), dp(14));
|
||||
panel.setVisibility(View.GONE);
|
||||
panel.setBackground(roundedRect(Color.WHITE, dp(8), Color.rgb(219, 226, 222), dp(1)));
|
||||
panel.setBackground(roundedRect(card(), dp(8), chipBg(), dp(1)));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
panel.setElevation(dp(4));
|
||||
}
|
||||
@@ -389,7 +423,7 @@ public class MainActivity extends Activity {
|
||||
|
||||
monthRow.addView(calendarNavButton("<", view -> changeVisibleMonth(-1)));
|
||||
|
||||
calendarMonthText = textView("", 18, COLOR_INK, Typeface.BOLD);
|
||||
calendarMonthText = textView("", 18, ink(), Typeface.BOLD);
|
||||
calendarMonthText.setGravity(Gravity.CENTER);
|
||||
monthRow.addView(calendarMonthText, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
@@ -418,7 +452,7 @@ public class MainActivity extends Activity {
|
||||
weekdays.setOrientation(LinearLayout.HORIZONTAL);
|
||||
String[] labels = {"L", "M", "X", "J", "V", "S", "D"};
|
||||
for (String label : labels) {
|
||||
TextView dayLabel = textView(label, 12, COLOR_MUTED, Typeface.BOLD);
|
||||
TextView dayLabel = textView(label, 12, muted(), Typeface.BOLD);
|
||||
dayLabel.setGravity(Gravity.CENTER);
|
||||
weekdays.addView(dayLabel, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
@@ -443,7 +477,7 @@ public class MainActivity extends Activity {
|
||||
private TextView calendarNavButton(String text, View.OnClickListener listener) {
|
||||
TextView button = textView(text, 22, COLOR_ACCENT, Typeface.BOLD);
|
||||
button.setGravity(Gravity.CENTER);
|
||||
button.setBackground(roundedRect(Color.rgb(229, 244, 240), dp(8), Color.TRANSPARENT, 0));
|
||||
button.setBackground(roundedRect(speakerBg(), dp(8), Color.TRANSPARENT, 0));
|
||||
button.setOnClickListener(listener);
|
||||
button.setContentDescription(text.equals("<") ? (isEnglish ? "Previous month" : "Mes anterior") : (isEnglish ? "Next month" : "Mes siguiente"));
|
||||
return button;
|
||||
@@ -453,7 +487,7 @@ public class MainActivity extends Activity {
|
||||
TextView button = textView(text, 13, COLOR_ACCENT, Typeface.BOLD);
|
||||
button.setGravity(Gravity.CENTER);
|
||||
button.setPadding(dp(8), 0, dp(8), 0);
|
||||
button.setBackground(roundedRect(Color.rgb(229, 244, 240), dp(8), Color.TRANSPARENT, 0));
|
||||
button.setBackground(roundedRect(speakerBg(), dp(8), Color.TRANSPARENT, 0));
|
||||
button.setOnClickListener(listener);
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
@@ -512,7 +546,7 @@ public class MainActivity extends Activity {
|
||||
Calendar today = startOfDay(Calendar.getInstance());
|
||||
|
||||
for (int cell = 0; cell < 42; cell++) {
|
||||
TextView dayCell = textView("", 16, COLOR_INK, Typeface.BOLD);
|
||||
TextView dayCell = textView("", 16, ink(), Typeface.BOLD);
|
||||
dayCell.setGravity(Gravity.CENTER);
|
||||
dayCell.setIncludeFontPadding(false);
|
||||
|
||||
@@ -540,7 +574,7 @@ public class MainActivity extends Activity {
|
||||
dayCell.setBackground(roundedRect(COLOR_HOLIDAY_BG, dp(8), COLOR_HOLIDAY_BORDER, dp(1)));
|
||||
} else if (isSameDay(cellDate, today)) {
|
||||
dayCell.setTextColor(COLOR_WARM);
|
||||
dayCell.setBackground(roundedRect(Color.rgb(255, 239, 236), dp(8), Color.TRANSPARENT, 0));
|
||||
dayCell.setBackground(roundedRect(todayBg(), dp(8), Color.TRANSPARENT, 0));
|
||||
} else {
|
||||
dayCell.setBackground(roundedRect(Color.TRANSPARENT, dp(8), Color.TRANSPARENT, 0));
|
||||
}
|
||||
@@ -983,7 +1017,7 @@ public class MainActivity extends Activity {
|
||||
statusBlock = new LinearLayout(this);
|
||||
statusBlock.setOrientation(LinearLayout.VERTICAL);
|
||||
statusBlock.setPadding(dp(18), dp(16), dp(18), dp(16));
|
||||
statusBlock.setBackground(roundedRect(COLOR_CARD, dp(8), Color.TRANSPARENT, 0));
|
||||
statusBlock.setBackground(roundedRect(card(), dp(8), Color.TRANSPARENT, 0));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
statusBlock.setElevation(dp(1));
|
||||
}
|
||||
@@ -997,7 +1031,7 @@ public class MainActivity extends Activity {
|
||||
progressParams.setMargins(0, 0, dp(12), 0);
|
||||
row.addView(progressBar, progressParams);
|
||||
|
||||
statusText = textView(isEnglish ? "Loading today's Word..." : "Cargando la Palabra de hoy...", 16, COLOR_INK, Typeface.NORMAL);
|
||||
statusText = textView(isEnglish ? "Loading today's Word..." : "Cargando la Palabra de hoy...", 16, ink(), Typeface.NORMAL);
|
||||
statusText.setLineSpacing(0, 1.16f);
|
||||
row.addView(statusText, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
@@ -1035,7 +1069,7 @@ public class MainActivity extends Activity {
|
||||
panel.setOrientation(LinearLayout.VERTICAL);
|
||||
panel.setPadding(dp(16), dp(14), dp(16), dp(14));
|
||||
panel.setVisibility(View.GONE);
|
||||
panel.setBackground(roundedRect(Color.WHITE, dp(8), Color.rgb(223, 229, 226), dp(1)));
|
||||
panel.setBackground(roundedRect(card(), dp(8), stroke(), dp(1)));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
panel.setElevation(dp(8));
|
||||
}
|
||||
@@ -1043,10 +1077,10 @@ public class MainActivity extends Activity {
|
||||
LinearLayout labelRow = new LinearLayout(this);
|
||||
labelRow.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
TextView label = textView(isEnglish ? "Font size" : "Tamaño de letra", 15, COLOR_INK, Typeface.BOLD);
|
||||
TextView label = textView(isEnglish ? "Font size" : "Tamaño de letra", 15, ink(), Typeface.BOLD);
|
||||
labelRow.addView(label, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
|
||||
|
||||
fontValueText = textView(Math.round(readingFontSp) + " sp", 14, COLOR_MUTED, Typeface.BOLD);
|
||||
fontValueText = textView(Math.round(readingFontSp) + " sp", 14, muted(), Typeface.BOLD);
|
||||
labelRow.addView(fontValueText);
|
||||
panel.addView(labelRow);
|
||||
|
||||
@@ -1380,7 +1414,7 @@ public class MainActivity extends Activity {
|
||||
button.setTextColor(COLOR_ACCENT);
|
||||
button.setTextSize(14);
|
||||
button.setAllCaps(false);
|
||||
button.setBackground(roundedRect(Color.WHITE, dp(8), Color.rgb(219, 226, 222), dp(1)));
|
||||
button.setBackground(roundedRect(card(), dp(8), stroke(), dp(1)));
|
||||
return button;
|
||||
}
|
||||
|
||||
@@ -1674,7 +1708,7 @@ public class MainActivity extends Activity {
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
TextView titleText = textView(title, titleSizeSp, COLOR_INK, Typeface.BOLD);
|
||||
TextView titleText = textView(title, titleSizeSp, ink(), Typeface.BOLD);
|
||||
titleText.setIncludeFontPadding(false);
|
||||
row.addView(titleText, new LinearLayout.LayoutParams(
|
||||
0,
|
||||
@@ -1686,7 +1720,7 @@ public class MainActivity extends Activity {
|
||||
speakerButton.setImageResource(R.drawable.ic_speaker_24);
|
||||
speakerButton.setColorFilter(COLOR_ACCENT);
|
||||
speakerButton.setPadding(dp(8), dp(8), dp(8), dp(8));
|
||||
speakerButton.setBackground(roundedRect(Color.rgb(229, 244, 240), dp(8), Color.TRANSPARENT, 0));
|
||||
speakerButton.setBackground(roundedRect(speakerBg(), dp(8), Color.TRANSPARENT, 0));
|
||||
speakerButton.setContentDescription((isEnglish ? "Listen to " : "Escuchar ") + title);
|
||||
speakerButton.setOnClickListener(view -> startTtsConversionForText(speechText, controls));
|
||||
|
||||
@@ -1697,7 +1731,7 @@ public class MainActivity extends Activity {
|
||||
}
|
||||
|
||||
private TtsControls createTtsControls() {
|
||||
TextView status = textView("", 14, COLOR_MUTED, Typeface.BOLD);
|
||||
TextView status = textView("", 14, muted(), Typeface.BOLD);
|
||||
status.setVisibility(View.GONE);
|
||||
|
||||
LinearLayout playerPanel = new LinearLayout(this);
|
||||
@@ -1738,7 +1772,7 @@ public class MainActivity extends Activity {
|
||||
seekParams.setMargins(dp(8), 0, dp(8), 0);
|
||||
playerPanel.addView(seekBar, seekParams);
|
||||
|
||||
TextView timeText = textView("0:00", 13, COLOR_MUTED, Typeface.BOLD);
|
||||
TextView timeText = textView("0:00", 13, muted(), Typeface.BOLD);
|
||||
timeText.setGravity(Gravity.CENTER_VERTICAL);
|
||||
playerPanel.addView(timeText, new LinearLayout.LayoutParams(
|
||||
dp(86),
|
||||
@@ -1797,7 +1831,7 @@ public class MainActivity extends Activity {
|
||||
addTtsControlsToCard(card, ttsControls);
|
||||
|
||||
if (!section.introduction.isEmpty()) {
|
||||
TextView introText = textView(section.introduction, 16, COLOR_MUTED, Typeface.BOLD);
|
||||
TextView introText = textView(section.introduction, 16, muted(), Typeface.BOLD);
|
||||
introText.setLineSpacing(0, 1.14f);
|
||||
resizableTextViews.add(introText);
|
||||
card.addView(introText);
|
||||
@@ -1806,7 +1840,7 @@ public class MainActivity extends Activity {
|
||||
if (!section.reference.isEmpty()) {
|
||||
TextView referenceText = textView(section.reference, 15, COLOR_ACCENT, Typeface.BOLD);
|
||||
referenceText.setGravity(Gravity.CENTER_VERTICAL);
|
||||
referenceText.setBackground(roundedRect(Color.rgb(229, 244, 240), dp(8), Color.TRANSPARENT, 0));
|
||||
referenceText.setBackground(roundedRect(referenceBg(), dp(8), Color.TRANSPARENT, 0));
|
||||
referenceText.setPadding(dp(10), dp(6), dp(10), dp(6));
|
||||
LinearLayout.LayoutParams referenceParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
@@ -1816,7 +1850,7 @@ public class MainActivity extends Activity {
|
||||
card.addView(referenceText, referenceParams);
|
||||
}
|
||||
|
||||
TextView bodyText = textView(section.body, Math.round(readingFontSp), COLOR_INK, Typeface.NORMAL);
|
||||
TextView bodyText = textView(section.body, Math.round(readingFontSp), ink(), Typeface.NORMAL);
|
||||
bodyText.setLineSpacing(dp(4), 1.16f);
|
||||
resizableTextViews.add(bodyText);
|
||||
card.addView(bodyText);
|
||||
@@ -1841,7 +1875,7 @@ public class MainActivity extends Activity {
|
||||
));
|
||||
addTtsControlsToCard(card, ttsControls);
|
||||
|
||||
TextView body = textView(section.body, Math.round(readingFontSp), COLOR_INK, Typeface.NORMAL);
|
||||
TextView body = textView(section.body, Math.round(readingFontSp), ink(), Typeface.NORMAL);
|
||||
body.setLineSpacing(dp(4), 1.16f);
|
||||
LinearLayout.LayoutParams bodyParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
@@ -1858,7 +1892,7 @@ public class MainActivity extends Activity {
|
||||
LinearLayout card = new LinearLayout(this);
|
||||
card.setOrientation(LinearLayout.VERTICAL);
|
||||
card.setPadding(padding, padding, padding, padding);
|
||||
card.setBackground(roundedRect(COLOR_CARD, dp(8), Color.rgb(229, 232, 230), dp(1)));
|
||||
card.setBackground(roundedRect(card(), dp(8), stroke(), dp(1)));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
card.setElevation(dp(1));
|
||||
}
|
||||
@@ -2416,4 +2450,4 @@ public class MainActivity extends Activity {
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,10 +20,20 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class SettingsActivity extends Activity {
|
||||
private static final int COLOR_BACKGROUND = Color.rgb(247, 248, 246);
|
||||
private static final int COLOR_CARD = Color.WHITE;
|
||||
private static final int COLOR_INK = Color.rgb(25, 31, 31);
|
||||
private static final int COLOR_MUTED = Color.rgb(91, 99, 98);
|
||||
// Light mode colors
|
||||
private static final int COLOR_BG_LIGHT = Color.rgb(247, 248, 246);
|
||||
private static final int COLOR_CARD_LIGHT = Color.WHITE;
|
||||
private static final int COLOR_INK_LIGHT = Color.rgb(25, 31, 31);
|
||||
private static final int COLOR_MUTED_LIGHT = Color.rgb(91, 99, 98);
|
||||
private static final int COLOR_STROKE_LIGHT = Color.rgb(219, 226, 222);
|
||||
|
||||
// Dark mode colors
|
||||
private static final int COLOR_BG_DARK = Color.rgb(26, 28, 30);
|
||||
private static final int COLOR_CARD_DARK = Color.rgb(38, 41, 44);
|
||||
private static final int COLOR_INK_DARK = Color.rgb(224, 226, 219);
|
||||
private static final int COLOR_MUTED_DARK = Color.rgb(158, 163, 160);
|
||||
private static final int COLOR_STROKE_DARK = Color.rgb(58, 62, 65);
|
||||
|
||||
private static final int COLOR_ACCENT = Color.rgb(0, 107, 90);
|
||||
private static final int COLOR_WARM = Color.rgb(217, 75, 61);
|
||||
|
||||
@@ -183,11 +193,11 @@ public class SettingsActivity extends Activity {
|
||||
1f
|
||||
));
|
||||
|
||||
TextView langToggle = actionButton(UpdateManager.isEnglish(this) ? "English" : "Español", COLOR_ACCENT, Color.WHITE);
|
||||
TextView langToggle = actionButton(UpdateManager.isEnglish(this) ? "English" : "Español", COLOR_ACCENT, Color.WHITE);
|
||||
langToggle.setOnClickListener(view -> {
|
||||
boolean current = UpdateManager.isEnglish(this);
|
||||
UpdateManager.setEnglish(this, !current);
|
||||
langToggle.setText(!current ? "English" : "Español");
|
||||
langToggle.setText(!current ? "English" : "Español");
|
||||
updateVoiceCard();
|
||||
});
|
||||
card.addView(langToggle, new LinearLayout.LayoutParams(dp(100), dp(40)));
|
||||
@@ -338,7 +348,7 @@ public class SettingsActivity extends Activity {
|
||||
String voiceId = UpdateManager.getTtsVoice(this, english);
|
||||
voiceSubtitleText.setText(english
|
||||
? "English voices are shown while English is selected"
|
||||
: "Las voces en español se muestran mientras el español esté seleccionado");
|
||||
: "Las voces en español se muestran mientras el español esté seleccionado");
|
||||
voiceButton.setText(UpdateManager.getTtsVoiceLabel(english, voiceId));
|
||||
}
|
||||
|
||||
@@ -349,7 +359,7 @@ public class SettingsActivity extends Activity {
|
||||
+ UpdateManager.getInstalledVersionName(this)
|
||||
+ " (" + UpdateManager.getInstalledVersionCode(this) + ")");
|
||||
} catch (Exception error) {
|
||||
installedVersionText.setText(isEnglish ? "Installed version unavailable." : "Versión instalada no disponible.");
|
||||
installedVersionText.setText(isEnglish ? "Installed version unavailable." : "Versión instalada no disponible.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ final class UpdateManager {
|
||||
static final String PREFS_NAME = "preferencias_lectura";
|
||||
static final String KEY_AUTO_UPDATES = "auto_updates_enabled";
|
||||
static final String KEY_IS_ENGLISH = "is_english";
|
||||
static final String KEY_DARK_MODE = "dark_mode";
|
||||
static final String KEY_TTS_VOICE_ENGLISH = "tts_voice_english";
|
||||
static final String KEY_TTS_VOICE_SPANISH = "tts_voice_spanish";
|
||||
static final String DEFAULT_TTS_VOICE_ENGLISH = "af_heart";
|
||||
@@ -89,6 +90,14 @@ final class UpdateManager {
|
||||
preferences(context).edit().putBoolean(KEY_IS_ENGLISH, enabled).apply();
|
||||
}
|
||||
|
||||
static boolean isDarkMode(Context context) {
|
||||
return preferences(context).getBoolean(KEY_DARK_MODE, false);
|
||||
}
|
||||
|
||||
static void setDarkMode(Context context, boolean enabled) {
|
||||
preferences(context).edit().putBoolean(KEY_DARK_MODE, enabled).apply();
|
||||
}
|
||||
|
||||
static VoiceOption[] getTtsVoiceOptions(boolean isEnglish) {
|
||||
return isEnglish ? ENGLISH_VOICES : SPANISH_VOICES;
|
||||
}
|
||||
@@ -207,10 +216,10 @@ final class UpdateManager {
|
||||
|
||||
boolean english = isEnglish(activity);
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(english ? "Update available" : "Actualización disponible")
|
||||
.setMessage((english ? "Version " : "Versión ") + version + (english ? " is ready to download." : " está lista para descargar."))
|
||||
.setTitle(english ? "Update available" : "Actualización disponible")
|
||||
.setMessage((english ? "Version " : "Versión ") + version + (english ? " is ready to download." : " está lista para descargar."))
|
||||
.setPositiveButton(english ? "Download" : "Descargar", (dialog, which) -> openDownload(activity, info.apkUrl))
|
||||
.setNegativeButton(english ? "Later" : "Después", null)
|
||||
.setNegativeButton(english ? "Later" : "Después", null)
|
||||
.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="AppTheme" parent="android:style/Theme.Material.NoActionBar">
|
||||
<item name="android:fontFamily">sans</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:colorAccent">#006B5A</item>
|
||||
<item name="android:navigationBarColor">#1A1C1E</item>
|
||||
<item name="android:windowActionModeOverlay">true</item>
|
||||
</style>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user