From 4d0b8b4672d33212cbdbee9f835d4f29f178523a Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Fri, 14 Jan 2022 20:57:16 +0800 Subject: [PATCH] Add options to set custom fonts. --- .../infinityforreddit/AppComponent.java | 3 + .../infinityforreddit/Infinity.java | 13 +- .../activities/PostImageActivity.java | 2 +- .../font/ContentFontFamily.java | 3 +- .../infinityforreddit/font/FontFamily.java | 3 +- .../font/TitleFontFamily.java | 3 +- .../settings/FontPreferenceFragment.java | 180 ++++++++++++++++++ .../utils/SharedPreferencesUtils.java | 3 + app/src/main/res/values/arrays.xml | 2 + app/src/main/res/values/strings.xml | 8 + app/src/main/res/xml/font_preferences.xml | 15 ++ 11 files changed, 224 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index 54e54567..1f758dfc 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -86,6 +86,7 @@ import ml.docilealligator.infinityforreddit.settings.CrashReportsFragment; import ml.docilealligator.infinityforreddit.settings.CustomizeBottomAppBarFragment; import ml.docilealligator.infinityforreddit.settings.CustomizeMainPageTabsFragment; import ml.docilealligator.infinityforreddit.settings.DownloadLocationPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.FontPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.GesturesAndButtonsPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.MainPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.MiscellaneousPreferenceFragment; @@ -289,4 +290,6 @@ public interface AppComponent { void inject(EditProfileService editProfileService); void inject(EditProfileActivity editProfileActivity); + + void inject(FontPreferenceFragment fontPreferenceFragment); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java index f6b5706d..a1e966de 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java @@ -28,7 +28,6 @@ import org.greenrobot.eventbus.Subscribe; import javax.inject.Inject; import javax.inject.Named; -import ml.docilealligator.infinityforreddit.activities.BaseActivity; import ml.docilealligator.infinityforreddit.activities.LockScreenActivity; import ml.docilealligator.infinityforreddit.broadcastreceivers.NetworkWifiStatusReceiver; import ml.docilealligator.infinityforreddit.broadcastreceivers.WallpaperChangeReceiver; @@ -39,15 +38,15 @@ import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; public class Infinity extends Application implements LifecycleObserver { + public Typeface typeface; + public Typeface titleTypeface; + public Typeface contentTypeface; private AppComponent mAppComponent; private NetworkWifiStatusReceiver mNetworkWifiStatusReceiver; private boolean appLock; private long appLockTimeout; private boolean canStartLockScreenActivity = false; private boolean isSecureMode; - private Typeface typeface; - private Typeface titleTypeface; - private Typeface contentTypeface; @Inject @Named("default") SharedPreferences mSharedPreferences; @@ -70,9 +69,9 @@ public class Infinity extends Application implements LifecycleObserver { isSecureMode = mSecuritySharedPreferences.getBoolean(SharedPreferencesUtils.SECURE_MODE, false); try { - typeface = Typeface.createFromFile(getCacheDir() + "/opensans.ttf"); - titleTypeface = Typeface.createFromFile(getCacheDir() + "/opensans.ttf"); - contentTypeface = Typeface.createFromFile(getCacheDir() + "/opensans.ttf"); + typeface = Typeface.createFromFile(getExternalFilesDir("fonts") + "/font_family.ttf"); + titleTypeface = Typeface.createFromFile(getExternalFilesDir("fonts") + "/title_font_family.ttf"); + contentTypeface = Typeface.createFromFile(getExternalFilesDir("fonts") + "/content_font_family.ttf"); } catch (RuntimeException e) { e.printStackTrace(); Toast.makeText(this, "Some font files do not exist", Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java index 1acc53e7..d2adceeb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java @@ -360,7 +360,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); - startActivityForResult(Intent.createChooser(intent, resources.getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); + startActivityForResult(Intent.createChooser(intent, getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); }); selectAgainTextView.setOnClickListener(view -> { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java index 1445c503..58d09d06 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java @@ -16,7 +16,8 @@ public enum ContentFontFamily { InterBold(R.style.ContentFontFamily_InterBold, "InterBold"), Manrope(R.style.ContentFontFamily_Manrope, "Manrope"), ManropeBold(R.style.ContentFontFamily_ManropeBold, "ManropeBold"), - Sriracha(R.style.ContentFontFamily_Sriracha, "Sriracha"); + Sriracha(R.style.ContentFontFamily_Sriracha, "Sriracha"), + Custom(R.style.ContentFontFamily, "Custom"); private int resId; private String title; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java index c04111e5..c4bfa873 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java @@ -16,7 +16,8 @@ public enum FontFamily { InterBold(R.style.FontFamily_InterBold, "InterBold"), Manrope(R.style.FontFamily_Manrope, "Manrope"), ManropeBold(R.style.FontFamily_ManropeBold, "ManropeBold"), - Sriracha(R.style.FontFamily_Sriracha, "Sriracha"); + Sriracha(R.style.FontFamily_Sriracha, "Sriracha"), + Custom(R.style.FontFamily, "Custom"); private int resId; private String title; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java index 60855f54..fc7299c5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java @@ -16,7 +16,8 @@ public enum TitleFontFamily { InterBold(R.style.TitleFontFamily_InterBold, "InterBold"), Manrope(R.style.TitleFontFamily_Manrope, "Manrope"), ManropeBold(R.style.TitleFontFamily_ManropeBold, "ManropeBold"), - Sriracha(R.style.TitleFontFamily_Sriracha, "Sriracha"); + Sriracha(R.style.TitleFontFamily_Sriracha, "Sriracha"), + Custom(R.style.TitleFontFamily, "Custom"); private int resId; private String title; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java index 5ebae9d9..7c84a164 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java @@ -1,34 +1,90 @@ package ml.docilealligator.infinityforreddit.settings; +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Typeface; +import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.widget.Toast; +import androidx.annotation.Nullable; import androidx.core.app.ActivityCompat; +import androidx.documentfile.provider.DocumentFile; import androidx.preference.ListPreference; +import androidx.preference.Preference; import org.greenrobot.eventbus.EventBus; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.customviews.CustomFontPreferenceFragmentCompat; import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontFamily; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; public class FontPreferenceFragment extends CustomFontPreferenceFragmentCompat { + private static final int CUSTOM_FONT_FAMILY_REQUEST_CODE = 20; + private static final int CUSTOM_TITLE_FONT_FAMILY_REQUEST_CODE = 21; + private static final int CUSTOM_CONTENT_FONT_FAMILY_REQUEST_CODE = 22; + + @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + Executor executor; + private Preference customFontFamilyPreference; + private Preference customTitleFontFamilyPreference; + private Preference customContentFontFamilyPreference; + @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.font_preferences, rootKey); + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + if (activity.typeface != null) { setFont(activity.typeface); } ListPreference fontFamilyPreference = findPreference(SharedPreferencesUtils.FONT_FAMILY_KEY); + customFontFamilyPreference = findPreference(SharedPreferencesUtils.CUSTOM_FONT_FAMILY_KEY); ListPreference titleFontFamilyPreference = findPreference(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY); + customTitleFontFamilyPreference = findPreference(SharedPreferencesUtils.CUSTOM_TITLE_FONT_FAMILY_KEY); ListPreference contentFontFamilyPreference = findPreference(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY); + customContentFontFamilyPreference = findPreference(SharedPreferencesUtils.CUSTOM_CONTENT_FONT_FAMILY_KEY); ListPreference fontSizePreference = findPreference(SharedPreferencesUtils.FONT_SIZE_KEY); ListPreference titleFontSizePreference = findPreference(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY); ListPreference contentFontSizePreference = findPreference(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY); + if (customFontFamilyPreference != null) { + if (sharedPreferences.getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name()).equals(FontFamily.Custom.name())) { + customFontFamilyPreference.setVisible(true); + } + + customFontFamilyPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(); + intent.setType("*/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, getString(R.string.select_a_ttf_font)), CUSTOM_FONT_FAMILY_REQUEST_CODE); + return true; + }); + } + if (fontFamilyPreference != null) { fontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { EventBus.getDefault().post(new RecreateActivityEvent()); @@ -37,6 +93,20 @@ public class FontPreferenceFragment extends CustomFontPreferenceFragmentCompat { }); } + if (customTitleFontFamilyPreference != null) { + if (sharedPreferences.getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name()).equals(TitleFontFamily.Custom.name())) { + customTitleFontFamilyPreference.setVisible(true); + } + + customTitleFontFamilyPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(); + intent.setType("*/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, getString(R.string.select_a_ttf_font)), CUSTOM_TITLE_FONT_FAMILY_REQUEST_CODE); + return true; + }); + } + if (titleFontFamilyPreference != null) { titleFontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { EventBus.getDefault().post(new RecreateActivityEvent()); @@ -44,6 +114,20 @@ public class FontPreferenceFragment extends CustomFontPreferenceFragmentCompat { }); } + if (customContentFontFamilyPreference != null) { + if (sharedPreferences.getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name()).equals(ContentFontFamily.Custom.name())) { + customContentFontFamilyPreference.setVisible(true); + } + + customContentFontFamilyPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(); + intent.setType("*/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, getString(R.string.select_a_ttf_font)), CUSTOM_CONTENT_FONT_FAMILY_REQUEST_CODE); + return true; + }); + } + if (contentFontFamilyPreference != null) { contentFontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { EventBus.getDefault().post(new RecreateActivityEvent()); @@ -73,4 +157,100 @@ public class FontPreferenceFragment extends CustomFontPreferenceFragmentCompat { }); } } + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) { + if (requestCode == CUSTOM_FONT_FAMILY_REQUEST_CODE) { + copyFontToInternalStorage(data.getData(), 0); + if (customFontFamilyPreference != null) { + customFontFamilyPreference.setSummary(data.getDataString()); + } + } else if (requestCode == CUSTOM_TITLE_FONT_FAMILY_REQUEST_CODE) { + copyFontToInternalStorage(data.getData(), 1); + } else if (requestCode == CUSTOM_CONTENT_FONT_FAMILY_REQUEST_CODE) { + copyFontToInternalStorage(data.getData(), 2); + if (customContentFontFamilyPreference != null) { + customContentFontFamilyPreference.setSummary(data.getDataString()); + } + } + } + } + + private void copyFontToInternalStorage(Uri uri, int type) { + String destinationFontName; + switch (type) { + case 1: + destinationFontName = "title_font_family.ttf"; + break; + case 2: + destinationFontName = "content_font_family.ttf"; + break; + default: + destinationFontName = "font_family.ttf"; + } + File fontDestinationPath = activity.getExternalFilesDir("fonts"); + + Handler handler = new Handler(); + + executor.execute(() -> { + File destinationFontFile = new File(fontDestinationPath, destinationFontName); + DocumentFile documentFile = DocumentFile.fromSingleUri(activity, uri); + try (InputStream in = activity.getContentResolver().openInputStream(uri); + OutputStream out = new FileOutputStream(destinationFontFile)) { + if (in != null) { + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + try { + switch (type) { + case 1: + ((Infinity) activity.getApplication()).titleTypeface = Typeface.createFromFile(destinationFontFile); + break; + case 2: + ((Infinity) activity.getApplication()).contentTypeface = Typeface.createFromFile(destinationFontFile); + break; + default: + ((Infinity) activity.getApplication()).typeface = Typeface.createFromFile(destinationFontFile); + } + } catch (RuntimeException e) { + e.printStackTrace(); + handler.post(() -> Toast.makeText(activity, R.string.unable_to_load_font, Toast.LENGTH_SHORT).show()); + return; + } + } else { + handler.post(() -> Toast.makeText(activity, R.string.unable_to_get_font_file, Toast.LENGTH_SHORT).show()); + return; + } + handler.post(() -> { + switch (type) { + case 1: + if (customTitleFontFamilyPreference != null) { + customTitleFontFamilyPreference.setSummary(uri.toString()); + } + break; + case 2: + if (customContentFontFamilyPreference != null) { + customContentFontFamilyPreference.setSummary(uri.toString()); + } + break; + default: + if (customFontFamilyPreference != null) { + customFontFamilyPreference.setSummary(uri.toString()); + } + } + EventBus.getDefault().post(new RecreateActivityEvent()); + ActivityCompat.recreate(activity); + }); + } catch (IOException e) { + e.printStackTrace(); + handler.post(() -> { + Toast.makeText(activity, R.string.unable_to_copy_font_file, Toast.LENGTH_SHORT).show(); + }); + } + }); + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java index 296fc651..fad3a640 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java @@ -40,6 +40,9 @@ public class SharedPreferencesUtils { public static final String VOTE_BUTTONS_ON_THE_RIGHT_KEY = "vote_buttons_on_the_right"; public static final String SHOW_AVATAR_ON_THE_RIGHT = "show_avatar_on_the_right"; public static final String DEFAULT_SEARCH_RESULT_TAB = "default_search_result_tab"; + public static final String CUSTOM_FONT_FAMILY_KEY = "custom_font_family"; + public static final String CUSTOM_TITLE_FONT_FAMILY_KEY = "custom_title_font_family"; + public static final String CUSTOM_CONTENT_FONT_FAMILY_KEY = "custom_content_font_family"; public static final String SORT_TYPE_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.sort_type"; public static final String SORT_TYPE_BEST_POST = "sort_type_best_post"; diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index c54e574d..8c5c60aa 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -162,6 +162,7 @@ Manrope (No Italic) Manrope Bold (No Italic) Sriracha + @string/settings_custom_font_family_title @@ -179,6 +180,7 @@ Manrope ManropeBold Sriracha + Custom diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 11f1d66d..a82d844d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -619,6 +619,9 @@ Legacy Video Controller UI Pinch to Zoom Video Experimental feature + Custom Font Family + Custom Title Font Family + Custom Content Font Family Cannot get the link @@ -1245,4 +1248,9 @@ Save profile successfully Failed to save profile %s + Select a ttf font file + Unable to get your font + Unable to load custom font + Unable to copy your font + diff --git a/app/src/main/res/xml/font_preferences.xml b/app/src/main/res/xml/font_preferences.xml index 24b1febe..14db4bb4 100644 --- a/app/src/main/res/xml/font_preferences.xml +++ b/app/src/main/res/xml/font_preferences.xml @@ -17,6 +17,11 @@ app:title="@string/settings_font_family_title" app:useSimpleSummaryProvider="true" /> + + + + + +