diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 884ca57..a22859c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,7 +11,7 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme.Dark"> + android:theme="@style/AppTheme"> diff --git a/app/src/main/java/com/luca0n/joguitos/pluck/activities/BaseActivity.java b/app/src/main/java/com/luca0n/joguitos/pluck/activities/BaseActivity.java index dc57b9f..fb51e3f 100644 --- a/app/src/main/java/com/luca0n/joguitos/pluck/activities/BaseActivity.java +++ b/app/src/main/java/com/luca0n/joguitos/pluck/activities/BaseActivity.java @@ -24,6 +24,7 @@ Contact us at . package com.luca0n.joguitos.pluck.activities; import android.annotation.SuppressLint; +import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.MenuInflater; @@ -35,48 +36,65 @@ import com.mikepenz.aboutlibraries.LibsBuilder; import androidx.appcompat.app.AppCompatActivity; import com.luca0n.joguitos.pluck.R; import com.luca0n.joguitos.pluck.settings.SettingsActivity; +import com.luca0n.joguitos.pluck.util.UiUtil; @SuppressLint("Registered") public class BaseActivity extends AppCompatActivity { + public static final int REQUEST_ACTIVITY_CLOSED = 1; - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.app_menu, menu); - return true; - } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.app_menu, menu); + return true; + } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.settings: - onSettings(); - return true; - case R.id.about: - onAbout(); - return true; - case android.R.id.home: - onBackPressed(); - default: - return super.onOptionsItemSelected(item); - } - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.settings: + onSettings(); + return true; + case R.id.about: + onAbout(); + return true; + case android.R.id.home: + onBackPressed(); + default: + return super.onOptionsItemSelected(item); + } + } - private void onSettings() { - Intent intent = new Intent(this, SettingsActivity.class); - startActivity(intent); - } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent extras){ + switch (requestCode){ + case REQUEST_ACTIVITY_CLOSED: + if (resultCode == Activity.RESULT_OK){ + // Check if the theme changed. + recreate(); + } + break; + default: + super.onActivityResult(requestCode, resultCode, extras); + break; + } + } - private void onAbout() { - String appName = getResources().getString(R.string.app_name); - String appDescription = getResources().getString(R.string.app_description); + private void onSettings() { + Intent intent = new Intent(this, SettingsActivity.class); + startActivityForResult(intent, REQUEST_ACTIVITY_CLOSED); + } - new LibsBuilder() - .withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR) - .withAboutIconShown(true) - .withAboutAppName(appName) - .withAboutVersionShownName(true) - .withAboutDescription(appDescription) - .start(this); - } + private void onAbout() { + String appName = getResources().getString(R.string.app_name); + String appDescription = getResources().getString(R.string.app_description); + + new LibsBuilder() + .withActivityStyle(UiUtil.getTheme(this).equals(getString(R.string.pref_ui_theme_entryValues_dark)) ? Libs.ActivityStyle.DARK : Libs.ActivityStyle.LIGHT) + .withAboutIconShown(true) + .withAboutAppName(appName) + .withAboutVersionShownName(true) + .withAboutDescription(appDescription) + .start(this); + } } diff --git a/app/src/main/java/com/luca0n/joguitos/pluck/activities/MainActivity.java b/app/src/main/java/com/luca0n/joguitos/pluck/activities/MainActivity.java index 3cb9f2e..677f9ea 100644 --- a/app/src/main/java/com/luca0n/joguitos/pluck/activities/MainActivity.java +++ b/app/src/main/java/com/luca0n/joguitos/pluck/activities/MainActivity.java @@ -43,6 +43,7 @@ import com.luca0n.joguitos.pluck.trivia.TriviaCategory; import com.luca0n.joguitos.pluck.trivia.TriviaDifficulty; import com.luca0n.joguitos.pluck.trivia.TriviaQuery; import com.luca0n.joguitos.pluck.trivia.TriviaFilters; +import com.luca0n.joguitos.pluck.util.UiUtil; public class MainActivity extends BaseActivity { @@ -61,6 +62,7 @@ public class MainActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { + UiUtil.setTheme(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); @@ -129,7 +131,7 @@ public class MainActivity extends BaseActivity { .category(category) .difficulty(difficulty) .build()); - startActivity(intent); + startActivityForResult(intent, BaseActivity.REQUEST_ACTIVITY_CLOSED); }); // Create a String array that holds all options for spinnerNumber. @@ -191,6 +193,10 @@ public class MainActivity extends BaseActivity { .show(); } break; + case BaseActivity.REQUEST_ACTIVITY_CLOSED: + // Check if the theme changed. + recreate(); + break; default: super.onActivityResult(requestCode, resultCode, extras); break; diff --git a/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameActivity.java b/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameActivity.java index 2007448..d566d90 100644 --- a/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameActivity.java +++ b/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameActivity.java @@ -23,6 +23,7 @@ Contact us at . package com.luca0n.joguitos.pluck.activities; +import android.app.Activity; import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.PorterDuff; @@ -66,6 +67,7 @@ import com.luca0n.joguitos.pluck.trivia.TriviaSource; import com.luca0n.joguitos.pluck.trivia.TriviaFilters; import com.luca0n.joguitos.pluck.util.ApiUtil; import com.luca0n.joguitos.pluck.util.SoundUtil; +import com.luca0n.joguitos.pluck.util.UiUtil; public class TriviaGameActivity extends BaseActivity implements IDownloadTriviaQuestionReceiver { @@ -92,10 +94,13 @@ public class TriviaGameActivity extends BaseActivity @Override protected void onCreate(Bundle savedInstanceState) { + UiUtil.setTheme(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_trivia_game); ButterKnife.bind(this); + setResult(Activity.RESULT_OK); + ActionBar actionBar = getSupportActionBar(); if (actionBar != null) actionBar.setDisplayHomeAsUpEnabled(true); diff --git a/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameResultsActivity.java b/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameResultsActivity.java index bdfc09c..5c98e70 100644 --- a/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameResultsActivity.java +++ b/app/src/main/java/com/luca0n/joguitos/pluck/activities/TriviaGameResultsActivity.java @@ -31,55 +31,57 @@ import butterknife.BindView; import butterknife.ButterKnife; import com.luca0n.joguitos.pluck.R; import com.luca0n.joguitos.pluck.trivia.TriviaGame; +import com.luca0n.joguitos.pluck.util.UiUtil; public class TriviaGameResultsActivity extends BaseActivity { - static final String EXTRA_TRIVIA_GAME = "extra_trivia_game"; + static final String EXTRA_TRIVIA_GAME = "extra_trivia_game"; - @BindView(R.id.text_results_correct) - TextView textResultsCorrect; - @BindView(R.id.text_results_wrong) - TextView textResultsWrong; - @BindView(R.id.text_results_total) - TextView textResultsTotal; - @BindView(R.id.text_results_time_elapsed) - TextView textResultsTimeElapsed; - @BindView(R.id.button_return_to_menu) - Button buttonReturnToMenu; + @BindView(R.id.text_results_correct) + TextView textResultsCorrect; + @BindView(R.id.text_results_wrong) + TextView textResultsWrong; + @BindView(R.id.text_results_total) + TextView textResultsTotal; + @BindView(R.id.text_results_time_elapsed) + TextView textResultsTimeElapsed; + @BindView(R.id.button_return_to_menu) + Button buttonReturnToMenu; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_trivia_game_results); - ButterKnife.bind(this); + @Override + protected void onCreate(Bundle savedInstanceState) { + UiUtil.setTheme(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_trivia_game_results); + ButterKnife.bind(this); - Bundle bundle = getIntent().getExtras(); - TriviaGame game = (TriviaGame) bundle.get(EXTRA_TRIVIA_GAME); + Bundle bundle = getIntent().getExtras(); + TriviaGame game = (TriviaGame) bundle.get(EXTRA_TRIVIA_GAME); - int correctTotal = 0; + int correctTotal = 0; - for (boolean result : game.getResults()) { - if (result) { - correctTotal++; - } - } + for (boolean result : game.getResults()) { + if (result) { + correctTotal++; + } + } - // Calculate the difference between startEpoch and endEpoch - float timeDifference = (game.getEndEpoch() - game.getStartEpoch())/1000F; + // Calculate the difference between startEpoch and endEpoch + float timeDifference = (game.getEndEpoch() - game.getStartEpoch())/1000F; - textResultsCorrect.setText(String.valueOf(correctTotal)); - textResultsWrong.setText(String.valueOf(game.getQuestionsCount() - correctTotal)); - textResultsTotal.setText(String.valueOf(game.getQuestionsCount())); - if (timeDifference < 60000L) - // Use the "n seconds" string since the time difference was less than 60 seconds. - textResultsTimeElapsed.setText( - String.format(getString(R.string.ui_results_time_elapsed_format_seconds), timeDifference) - ); - else - // Use the "n minutes" string since the time difference was equal to or more than 60 seconds. - textResultsTimeElapsed.setText( - String.format(getString(R.string.ui_results_time_elapsed_format_minutes), timeDifference / 60F) - ); + textResultsCorrect.setText(String.valueOf(correctTotal)); + textResultsWrong.setText(String.valueOf(game.getQuestionsCount() - correctTotal)); + textResultsTotal.setText(String.valueOf(game.getQuestionsCount())); + if (timeDifference < 60000L) + // Use the "n seconds" string since the time difference was less than 60 seconds. + textResultsTimeElapsed.setText( + String.format(getString(R.string.ui_results_time_elapsed_format_seconds), timeDifference) + ); + else + // Use the "n minutes" string since the time difference was equal to or more than 60 seconds. + textResultsTimeElapsed.setText( + String.format(getString(R.string.ui_results_time_elapsed_format_minutes), timeDifference / 60F) + ); - buttonReturnToMenu.setOnClickListener(v -> finish()); - } + buttonReturnToMenu.setOnClickListener(v -> finish()); + } } diff --git a/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsActivity.java b/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsActivity.java index 34e362d..8c049ce 100644 --- a/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsActivity.java +++ b/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsActivity.java @@ -23,6 +23,7 @@ Contact us at . package com.luca0n.joguitos.pluck.settings; +import android.app.Activity; import android.os.Bundle; import android.view.MenuItem; @@ -30,19 +31,23 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; +import com.luca0n.joguitos.pluck.util.UiUtil; + public class SettingsActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + UiUtil.setTheme(this); super.onCreate(savedInstanceState); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) actionBar.setDisplayHomeAsUpEnabled(true); - getFragmentManager() + getSupportFragmentManager() .beginTransaction() .replace(android.R.id.content, new SettingsFragment()) .commit(); + setResult(Activity.RESULT_OK); } @Override diff --git a/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsFragment.java b/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsFragment.java index 6c23564..ec15150 100644 --- a/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsFragment.java +++ b/app/src/main/java/com/luca0n/joguitos/pluck/settings/SettingsFragment.java @@ -24,15 +24,32 @@ Contact us at . package com.luca0n.joguitos.pluck.settings; import android.os.Bundle; -import android.preference.PreferenceFragment; +import androidx.preference.PreferenceFragmentCompat; import androidx.annotation.Nullable; -import com.luca0n.joguitos.pluck.R; +import androidx.preference.ListPreference; +import androidx.preference.Preference; -public class SettingsFragment extends PreferenceFragment { - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.preferences); - } +import com.luca0n.joguitos.pluck.R; +import com.luca0n.joguitos.pluck.util.UiUtil; + +public class SettingsFragment extends PreferenceFragmentCompat { + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey){ + addPreferencesFromResource(R.xml.preferences); + // Listen for theme preference changes + ListPreference preferenceTheme = (ListPreference) findPreference(getString(R.string.pref_ui_theme)); + preferenceTheme.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener(){ + @Override + public boolean onPreferenceChange(Preference preference, Object newValue){ + getActivity().recreate(); + return true; + } + }); + } } diff --git a/app/src/main/java/com/luca0n/joguitos/pluck/util/UiUtil.java b/app/src/main/java/com/luca0n/joguitos/pluck/util/UiUtil.java new file mode 100644 index 0000000..9ad1378 --- /dev/null +++ b/app/src/main/java/com/luca0n/joguitos/pluck/util/UiUtil.java @@ -0,0 +1,61 @@ +/* +Pluck: an open source trivia game for Android + +Copyright (C) 2021 Joguitos do luca0N! + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +This game is a fork of LibreTrivia, and its source code is available at +. + +Contact us at . +*/ + +package com.luca0n.joguitos.pluck.util; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import com.luca0n.joguitos.pluck.R; + +public class UiUtil { + /** + * Applies the theme selected by the user to the context. + * @param context The activity context. + * @since 2021-03-17 + */ + public static void setTheme(Context context){ + SharedPreferences s = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); + + String dark = context.getString(R.string.pref_ui_theme_entryValues_dark), + theme = getTheme(context); + + if (theme.equals(dark)) + context.setTheme(R.style.AppTheme_Dark); + else + context.setTheme(R.style.AppTheme); + } + + /** + * @return The app theme selected by the user. + * @param context The activity context. + * @since 2021-03-17 + */ + public static String getTheme(Context context){ + SharedPreferences s = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); + String themeKey = context.getString(R.string.pref_ui_theme), + themeLight = context.getString(R.string.pref_ui_theme_entryValues_light); + return s.getString(themeKey, themeLight); + } +} diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml new file mode 100644 index 0000000..12972ab --- /dev/null +++ b/app/src/main/res/values/arrays.xml @@ -0,0 +1,30 @@ + + + + + + pref_ui_theme_entryValues_light + pref_ui_theme_entryValues_dark + + diff --git a/app/src/main/res/values/pref_keys.xml b/app/src/main/res/values/pref_keys.xml index c7bb272..3e6969e 100644 --- a/app/src/main/res/values/pref_keys.xml +++ b/app/src/main/res/values/pref_keys.xml @@ -28,4 +28,8 @@ Contact us at . pref_network_tor pref_network_server https://opentdb.com/api.php + pref_ui_theme + pref_ui_theme_entryValues_light + pref_ui_theme_entryValues_dark + pref_ui_theme_entryValues_light diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2fab1c0..91cacb0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,97 +23,105 @@ Contact us at . --> - Pluck - An open source trivia game. + Pluck + An open source trivia game. - - General Knowledge - Entertainment: Books - Entertainment: Film - Entertainment: Music - Entertainment: Musicals & Theatres - Entertainment: Television - Entertainment: Video Games - Entertainment: Board Games - Entertainment: Japanese Anime & Manga - Entertainment: Cartoons & Animation - Entertainment: Comics - Science & Nature - Science: Computers - Science: Mathematics - Science: Gadgets - Mythology - Sports - Geography - History - Politics - Art - Celebrities - Animals - Vehicles + + General Knowledge + Entertainment: Books + Entertainment: Film + Entertainment: Music + Entertainment: Musicals & Theatres + Entertainment: Television + Entertainment: Video Games + Entertainment: Board Games + Entertainment: Japanese Anime & Manga + Entertainment: Cartoons & Animation + Entertainment: Comics + Science & Nature + Science: Computers + Science: Mathematics + Science: Gadgets + Mythology + Sports + Geography + History + Politics + Art + Celebrities + Animals + Vehicles - - Easy - Medium - Hard + + Easy + Medium + Hard - - Multiple Choice - True / False + + Multiple Choice + True / False - - Server - File + + Server + File - - Settings - About - Play - Start Game - Any - All - True - False - Correct - Wrong - Questions - Category - Difficulty - %1$d⁄%2$d - Quit Game - Are you sure you want to quit this game? - Correct Answers - Wrong Answers - Total Questions - Time Elapsed - %.1f seconds - %.1f minutes - Return To Menu - Source - This value specifies where the game should retrieve trivia data. By default, the game gathers trivia data from a server, but you can load trivia files with the "File" source option. - Notice: when using a server as the game source, this game connects to Open Trivia Database by default to gather trivia questions. Open Trivia Database is a collection of user-contributed questions that are licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC-BY-SA 4.0) license.\n\nYou can select a custom server in the game settings.\n\nIf you want to open a trivia file instead of getting trivia questions from a server, select "File" as the trivia game source above. + + Settings + About + Play + Start Game + Any + All + True + False + Correct + Wrong + Questions + Category + Difficulty + %1$d⁄%2$d + Quit Game + Are you sure you want to quit this game? + Correct Answers + Wrong Answers + Total Questions + Time Elapsed + %.1f seconds + %.1f minutes + Return To Menu + Source + This value specifies where the game should retrieve trivia data. By default, the game gathers trivia data from a server, but you can load trivia files with the "File" source option. + Notice: when using a server as the game source, this game connects to Open Trivia Database by default to gather trivia questions. Open Trivia Database is a collection of user-contributed questions that are licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC-BY-SA 4.0) license.\n\nYou can select a custom server in the game settings.\n\nIf you want to open a trivia file instead of getting trivia questions from a server, select "File" as the trivia game source above. - - Error - Network error!\n\nCould not connect to a network. Check if your custom server address is correct. If Tor is enabled in the game settings, check if Orbot is running and then try again. - No trivia results!\n\nWas not able to find trivia questions that satisfied all options. - Server response error!\n\nCould not parse the server response. The server response may be in a unsupported version. If you are using a custom server, make sure the server address points to a valid address and then try again. - An unknown error occurred! - Trivia files are not supported in this version of Android. - Invalid trivia file!\n\nTrivia files should be in a plain text JSON format. - An unknown error occurred while attempting to read the opened file. - The selected question amount is only available for the "File" trivia game source. + + Error + Network error!\n\nCould not connect to a network. Check if your custom server address is correct. If Tor is enabled in the game settings, check if Orbot is running and then try again. + No trivia results!\n\nWas not able to find trivia questions that satisfied all options. + Server response error!\n\nCould not parse the server response. The server response may be in a unsupported version. If you are using a custom server, make sure the server address points to a valid address and then try again. + An unknown error occurred! + Trivia files are not supported in this version of Android. + Invalid trivia file!\n\nTrivia files should be in a plain text JSON format. + An unknown error occurred while attempting to read the opened file. + The selected question amount is only available for the "File" trivia game source. - Settings + Settings - - Sound - Answer Sound Effect - Toggles game sound effects. + + Sound + Answer Sound Effect + Toggles game sound effects. - Network - Connect Using Tor - Retrieves trivia data via the Tor network. Requires Orbot (recommended) or a Tor daemon with a SOCKS5 proxy listening on port 9050. - Server Address - Specifies the server location used by the game to fetch questions when using a server as the trivia source. Leave this setting empty to use the default server. + Network + Connect Using Tor + Retrieves trivia data via the Tor network. Requires Orbot (recommended) or a Tor daemon with a SOCKS5 proxy listening on port 9050. + Server Address + Specifies the server location used by the game to fetch questions when using a server as the trivia source. Leave this setting empty to use the default server. + + Interface + Theme + Defines the game theme. + + Light + Dark + diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 4c35560..242f038 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -48,4 +48,14 @@ Contact us at . android:title="@string/pref_network_tor_title" android:summary="@string/pref_network_tor_summary" /> + + +