diff --git a/app/build.gradle b/app/build.gradle index 7a6adeb8e..f8ef5e336 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -124,5 +124,5 @@ dependencies { implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' implementation 'com.github.smarteist:autoimageslider:1.3.2' //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-2' - + implementation 'com.jaredrummler:colorpicker:1.1.0' } diff --git a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java index 15a77e67b..4fd2874a5 100644 --- a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java @@ -36,6 +36,7 @@ import com.google.android.material.tabs.TabLayout; import org.jetbrains.annotations.NotNull; import app.fedilab.android.R; +import app.fedilab.android.fragments.ColorSettingsFragment; import app.fedilab.android.fragments.ContentSettingsFragment; import app.fedilab.android.helper.Helper; @@ -98,6 +99,7 @@ public class SettingsActivity extends BaseActivity { tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.notifications))); tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.settings_category_label_interface))); tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.compose))); + tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.colors))); tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.hide_menu_items))); tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.administration))); tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.languages))); @@ -168,12 +170,14 @@ public class SettingsActivity extends BaseActivity { typeOfSettings = ContentSettingsFragment.type.COMPOSE; break; case 4: + return new ColorSettingsFragment(); + case 5: typeOfSettings = ContentSettingsFragment.type.MENU; break; - case 5: + case 6: typeOfSettings = ContentSettingsFragment.type.ADMIN; break; - case 6: + case 7: typeOfSettings = ContentSettingsFragment.type.LANGUAGE; break; default: @@ -189,7 +193,7 @@ public class SettingsActivity extends BaseActivity { @Override public int getCount() { - return 7; + return 8; } } diff --git a/app/src/main/java/app/fedilab/android/client/Entities/Status.java b/app/src/main/java/app/fedilab/android/client/Entities/Status.java index 83427bb66..f425d94c7 100644 --- a/app/src/main/java/app/fedilab/android/client/Entities/Status.java +++ b/app/src/main/java/app/fedilab/android/client/Entities/Status.java @@ -30,6 +30,7 @@ import android.os.Parcelable; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; +import androidx.preference.PreferenceManager; import android.text.Html; import android.text.Spannable; @@ -861,6 +862,19 @@ public class Status implements Parcelable { spannableStringT.removeSpan(span); } + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + int l_c = prefs.getInt("theme_link_color", -1); + if( l_c == -1) { + if (theme == THEME_DARK) + l_c = ContextCompat.getColor(context, R.color.dark_link_toot); + else if (theme == THEME_BLACK) + l_c = ContextCompat.getColor(context, R.color.black_link_toot); + else if (theme == THEME_LIGHT) + l_c = ContextCompat.getColor(context, R.color.light_link_toot); + } + final int link_color = l_c; + matcher = Helper.twitterPattern.matcher(spannableStringT); while (matcher.find()) { int matchStart = matcher.start(2); @@ -888,12 +902,7 @@ public class Status implements Parcelable { public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setUnderlineText(false); - if (theme == THEME_DARK) - ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot)); - else if (theme == THEME_BLACK) - ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot)); - else if (theme == THEME_LIGHT) - ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot)); + ds.setColor(link_color); } }, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } @@ -940,12 +949,7 @@ public class Status implements Parcelable { public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setUnderlineText(false); - if (theme == THEME_DARK) - ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot)); - else if (theme == THEME_BLACK) - ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot)); - else if (theme == THEME_LIGHT) - ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot)); + ds.setColor(link_color); } }, startPosition, endPosition, @@ -1022,12 +1026,7 @@ public class Status implements Parcelable { public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setUnderlineText(false); - if (theme == THEME_DARK) - ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot)); - else if (theme == THEME_BLACK) - ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot)); - else if (theme == THEME_LIGHT) - ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot)); + ds.setColor(link_color); } }, startPosition, endPosition, @@ -1059,12 +1058,7 @@ public class Status implements Parcelable { public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setUnderlineText(false); - if (theme == THEME_DARK) - ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot)); - else if (theme == THEME_BLACK) - ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot)); - else if (theme == THEME_LIGHT) - ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot)); + ds.setColor(link_color); } }, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); @@ -1093,12 +1087,7 @@ public class Status implements Parcelable { public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setUnderlineText(false); - if (theme == THEME_DARK) - ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot)); - else if (theme == THEME_BLACK) - ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot)); - else if (theme == THEME_LIGHT) - ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot)); + ds.setColor(link_color); } }, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); @@ -1109,6 +1098,20 @@ public class Status implements Parcelable { public static void transformTranslation(Context context, Status status) { + SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + int l_c = prefs.getInt("theme_link_color", -1); + if( l_c == -1) { + if (theme == THEME_DARK) + l_c = ContextCompat.getColor(context, R.color.dark_link_toot); + else if (theme == THEME_BLACK) + l_c = ContextCompat.getColor(context, R.color.black_link_toot); + else if (theme == THEME_LIGHT) + l_c = ContextCompat.getColor(context, R.color.light_link_toot); + } + final int link_color = l_c; + if (((Activity) context).isFinishing() || status == null) return; if ((status.getReblog() != null && status.getReblog().getContent() == null) || (status.getReblog() == null && status.getContent() == null)) @@ -1128,8 +1131,8 @@ public class Status implements Parcelable { } SpannableString contentSpanTranslated = status.getContentSpanTranslated(); Matcher matcherALink = Patterns.WEB_URL.matcher(contentSpanTranslated.toString()); - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + + while (matcherALink.find()) { int matchStart = matcherALink.start(); int matchEnd = matcherALink.end(); @@ -1148,12 +1151,7 @@ public class Status implements Parcelable { public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setUnderlineText(false); - if (theme == THEME_DARK) - ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot)); - else if (theme == THEME_BLACK) - ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot)); - else if (theme == THEME_LIGHT) - ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot)); + ds.setColor(link_color); } }, matchStart, matchEnd, diff --git a/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java index bc63e2aa0..76f30a6e6 100644 --- a/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java @@ -34,6 +34,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.content.ContextCompat; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.PopupMenu; +import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -215,6 +216,8 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On boolean confirmBoost = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true); boolean hide_notification_delete = sharedpreferences.getBoolean(Helper.SET_HIDE_DELETE_BUTTON_ON_TAB, false); + + if (theme == Helper.THEME_DARK) { holder.main_container_trans.setBackgroundColor(ContextCompat.getColor(context, R.color.notif_dark_1)); holder.main_container_trans.setAlpha(.5f); @@ -233,6 +236,12 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On style = R.style.Dialog; } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + int reblogColor = prefs.getInt("theme_statuses_color", -1); + if( holder.main_linear_container != null && reblogColor != -1 ){ + holder.main_linear_container.setBackgroundColor(reblogColor); + } + if (hide_notification_delete) holder.notification_delete.setVisibility(View.GONE); Drawable imgH = null; @@ -1492,7 +1501,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On RadioGroup radio_group; TextView number_votes, remaining_time; Button submit_vote, refresh_poll; - + LinearLayout main_linear_container; public View getView() { return itemView; } @@ -1546,6 +1555,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On remaining_time = itemView.findViewById(R.id.remaining_time); submit_vote = itemView.findViewById(R.id.submit_vote); refresh_poll = itemView.findViewById(R.id.refresh_poll); + main_linear_container = itemView.findViewById(R.id.main_linear_container); } diff --git a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java index f16baeff0..da32c1277 100644 --- a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java @@ -37,10 +37,12 @@ import android.os.Handler; import androidx.annotation.NonNull; import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.TooltipCompat; +import androidx.cardview.widget.CardView; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.content.ContextCompat; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.PopupMenu; +import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -56,6 +58,7 @@ import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.URLSpan; +import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.MenuItem; @@ -707,7 +710,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct Button quick_reply_button; ImageView quick_reply_privacy; View status_reply_indicator_top, reply_indicator_dot, status_reply_indicator_bottom, status_reply_indicator_diag_top, status_reply_indicator_diag_bottom; - + CardView main_card_container; + LinearLayout main_linear_container; public View getView() { return itemView; } @@ -842,6 +846,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct status_reply_indicator_diag_bottom.setBackgroundResource(R.drawable.diag_bottom); } } + main_card_container = itemView.findViewById(R.id.main_card_container); + main_linear_container = itemView.findViewById(R.id.main_linear_container); } void updateAnimatedEmoji() { @@ -2106,6 +2112,18 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct holder.status_boosted_by_info.setVisibility(View.GONE); } } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + int reblogColor = prefs.getInt("theme_boost_header_color", -1); + if( holder.status_boosted_by_info != null && reblogColor != -1 ){ + holder.status_boosted_by_info.setBackgroundColor(reblogColor); + } + int statusColor = prefs.getInt("theme_statuses_color", -1); + if( holder.main_card_container != null && statusColor != -1 ){ + holder.main_card_container.setBackgroundColor(statusColor); + } + if( holder.main_linear_container != null && statusColor != -1 ){ + holder.main_linear_container.setBackgroundColor(statusColor); + } if (type == RetrieveFeedsAsyncTask.Type.CONVERSATION && status.getConversationProfilePicture() != null) { holder.status_account_profile.setVisibility(View.GONE); holder.conversation_pp.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/app/fedilab/android/fragments/ColorSettingsFragment.java b/app/src/main/java/app/fedilab/android/fragments/ColorSettingsFragment.java new file mode 100644 index 000000000..0549a216e --- /dev/null +++ b/app/src/main/java/app/fedilab/android/fragments/ColorSettingsFragment.java @@ -0,0 +1,69 @@ +package app.fedilab.android.fragments; + +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Bundle; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.FragmentActivity; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; + +import app.fedilab.android.R; +import app.fedilab.android.helper.Helper; + + +public class ColorSettingsFragment extends PreferenceFragmentCompat { + + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + addPreferencesFromResource(R.xml.fragment_settings_color); + + Preference button = findPreference("reset_pref"); + FragmentActivity context = getActivity(); + int style; + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); + int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + if (theme == Helper.THEME_DARK) { + style = R.style.DialogDark; + } else if (theme == Helper.THEME_BLACK) { + style = R.style.DialogBlack; + } else { + style = R.style.Dialog; + } + PreferenceFragmentCompat preferenceFragmentCompat = this; + button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context, style); + dialogBuilder.setMessage(R.string.reset_color); + dialogBuilder.setPositiveButton(R.string.reset, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.remove("theme_boost_header_color"); + editor.remove("theme_statuses_color"); + editor.remove("theme_link_color"); + editor.commit(); + dialog.dismiss(); + setPreferenceScreen(null); + addPreferencesFromResource(R.xml.fragment_settings_color); + + } + }); + dialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + } + }); + AlertDialog alertDialog = dialogBuilder.create(); + alertDialog.setCancelable(false); + alertDialog.show(); + return true; + } + }); + + } +} \ No newline at end of file diff --git a/app/src/main/java/app/fedilab/android/fragments/ContentSettingsFragment.java b/app/src/main/java/app/fedilab/android/fragments/ContentSettingsFragment.java index e7151decf..959db1f91 100644 --- a/app/src/main/java/app/fedilab/android/fragments/ContentSettingsFragment.java +++ b/app/src/main/java/app/fedilab/android/fragments/ContentSettingsFragment.java @@ -119,6 +119,7 @@ import static app.fedilab.android.activities.BaseMainActivity.iconLauncher.FEDIV import static app.fedilab.android.activities.BaseMainActivity.iconLauncher.HERO; import static app.fedilab.android.activities.BaseMainActivity.iconLauncher.MASTALAB; import static app.fedilab.android.fragments.ContentSettingsFragment.type.ADMIN; +import static app.fedilab.android.fragments.ContentSettingsFragment.type.COLORS; import static app.fedilab.android.fragments.ContentSettingsFragment.type.COMPOSE; import static app.fedilab.android.fragments.ContentSettingsFragment.type.INTERFACE; import static app.fedilab.android.fragments.ContentSettingsFragment.type.LANGUAGE; @@ -177,7 +178,8 @@ public class ContentSettingsFragment extends Fragment implements OnRetrieveRemot INTERFACE, COMPOSE, LANGUAGE, - MENU + MENU, + COLORS } private List translators = new ArrayList<>(); private AccountSearchDevAdapter translatorManager; diff --git a/app/src/main/res/layout/drawer_notification.xml b/app/src/main/res/layout/drawer_notification.xml index 4795cfc72..317a876cf 100644 --- a/app/src/main/res/layout/drawer_notification.xml +++ b/app/src/main/res/layout/drawer_notification.xml @@ -22,6 +22,7 @@ android:id="@+id/card_status_container"> diff --git a/app/src/main/res/layout/drawer_status_compact.xml b/app/src/main/res/layout/drawer_status_compact.xml index a40b47d29..8ed9e6277 100644 --- a/app/src/main/res/layout/drawer_status_compact.xml +++ b/app/src/main/res/layout/drawer_status_compact.xml @@ -66,6 +66,7 @@ android:layout_marginTop="4dp" android:layout_marginEnd="2dp" android:layout_marginBottom="4dp" + android:id="@+id/main_card_container" style="?attr/cardStyleOver" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/drawer_status_console.xml b/app/src/main/res/layout/drawer_status_console.xml index cda838822..86aca5ba0 100644 --- a/app/src/main/res/layout/drawer_status_console.xml +++ b/app/src/main/res/layout/drawer_status_console.xml @@ -24,6 +24,7 @@ android:layout_height="wrap_content"> + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 27cfdb61d..eca343597 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1247,4 +1247,14 @@ Title for the video Join Peertube I am at least 16 years old and agree to the %1$s of this instance + Colors + Links + Change the color of links (URLs, mentions, tags, etc.) in messages + Reblogs header + Change the color of the header for reblogs + Posts + Bakground color of posts in timelines + Reset colors + Click here to reset all your custom colors + Reset \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index daefb9d55..5e758b0a2 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -20,6 +20,7 @@ @color/light_black @color/white @color/mastodonC2 + @color/white @color/mastodonC4 @style/CardViewStyle.Light @style/CardViewStyleOver.Light @@ -72,6 +73,7 @@ @style/CardViewStyleOver.Light @color/cardBorderLight @color/mastodonC2 + @color/white @color/black @color/mastodonC2 @color/mastodonC4 diff --git a/app/src/main/res/xml/fragment_settings_color.xml b/app/src/main/res/xml/fragment_settings_color.xml new file mode 100644 index 000000000..8c3b7d3ca --- /dev/null +++ b/app/src/main/res/xml/fragment_settings_color.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file