Merge branch 'develop'

This commit is contained in:
Thomas 2022-12-09 18:15:26 +01:00
commit 002bc4886b
110 changed files with 1792 additions and 587 deletions

View file

@ -13,8 +13,8 @@ android {
defaultConfig {
minSdk 21
targetSdk 32
versionCode 439
versionName "3.9.4"
versionCode 443
versionName "3.10.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
flavorDimensions "default"
@ -79,7 +79,11 @@ allprojects {
dependencies {
implementation project(':autoimageslider')
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'com.jaredrummler:colorpicker:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "com.google.code.gson:gson:2.9.1"
implementation 'com.squareup.retrofit2:retrofit:2.9.0'

View file

@ -1,4 +1,24 @@
[
{
"version": "3.10.0",
"code": "443",
"note": "Added:\n- Dracula theme\n- Customize message colors\n- Enable/Disable Card presentation\n\nChanged:\n- Colors for some themes\n- Space between buttons\n\nFixed:\n- Animated profile pictures not displayed\n- Mentions broken in profile bio and fields\n- Jumps with fit preview images when scrolling up\n- Fetch more button broken with cache\n- Tag patterns in URL break the link\n- Typo in followed tags"
},
{
"version": "3.9.7",
"code": "442",
"note": "Added:\n- Dracula theme\n\nChanged:\n- Colors for Light/Dark/Black themes\n\nFixed:\n- Animated profile pictures not displayed\n- Mentions broken in profile bio and fields\n- Tag patterns in URL break the link\n- Typo in followed tags"
},
{
"version": "3.9.6",
"code": "441",
"note": "Fixed:\n- Jumps with fit preview images when scrolling up\n- Fetch more button broken with cache"
},
{
"version": "3.9.5",
"code": "440",
"note": "Fixed:\n- Custom emoji are not always displayed\n- Jumps in timeline when using \"fit preview images\"\n- Dark theme: timeline buttons without toggle"
},
{
"version": "3.9.4",
"code": "439",

View file

@ -83,6 +83,10 @@ public class BaseActivity extends AppCompatActivity {
setTheme(R.style.BlackAppTheme);
currentThemeId = R.style.BlackAppTheme;
break;
case "DRACULA":
setTheme(R.style.DraculaAppTheme);
currentThemeId = R.style.DraculaAppTheme;
break;
}
break;
}
@ -113,6 +117,11 @@ public class BaseActivity extends AppCompatActivity {
setTheme(R.style.BlackAppTheme);
currentThemeId = R.style.BlackAppTheme;
break;
case "DRACULA":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.DraculaAppTheme);
currentThemeId = R.style.DraculaAppTheme;
break;
}
}
super.onCreate(savedInstanceState);

View file

@ -76,6 +76,9 @@ public class BaseAlertDialogActivity extends AppCompatActivity {
case "BLACK":
setTheme(R.style.BlackAlertDialog);
break;
case "DRACULA":
setTheme(R.style.DraculaAlertDialog);
break;
}
break;
}
@ -101,6 +104,10 @@ public class BaseAlertDialogActivity extends AppCompatActivity {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.BlackAlertDialog);
break;
case "DRACULA":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.DraculaAlertDialog);
break;
}
}
super.onCreate(savedInstanceState);

View file

@ -75,6 +75,9 @@ public class BaseBarActivity extends AppCompatActivity {
case "BLACK":
setTheme(R.style.BlackAppThemeBar);
break;
case "DRACULA":
setTheme(R.style.DraculaAppThemeBar);
break;
}
break;
}
@ -101,6 +104,10 @@ public class BaseBarActivity extends AppCompatActivity {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.BlackAppThemeBar);
break;
case "DRACULA":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.DraculaAppThemeBar);
break;
}
}
super.onCreate(savedInstanceState);

View file

@ -75,6 +75,9 @@ public class BaseTransparentActivity extends AppCompatActivity {
case "BLACK":
setTheme(R.style.TransparentBlack);
break;
case "DRACULA":
setTheme(R.style.TransparentDracula);
break;
}
break;
}
@ -101,6 +104,10 @@ public class BaseTransparentActivity extends AppCompatActivity {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.TransparentBlack);
break;
case "DRACULA":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.TransparentDracula);
break;
}
}
super.onCreate(savedInstanceState);

View file

@ -108,7 +108,7 @@ public class FollowedTagActivity extends BaseBarActivity implements FollowedTagA
fragmentMastodonTimeline.onDestroyView();
}
invalidateOptionsMenu();
setTitle(R.string.action_lists);
setTitle(R.string.followed_tags);
});
if (tagList.size() == 0) {
binding.notContent.setVisibility(View.VISIBLE);
@ -177,7 +177,7 @@ public class FollowedTagActivity extends BaseBarActivity implements FollowedTagA
fragmentMastodonTimeline.onDestroyView();
}
});
setTitle(R.string.action_lists);
setTitle(R.string.followed_tags);
invalidateOptionsMenu();
} else {
super.onBackPressed();

View file

@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.SpannableString;
@ -262,6 +263,7 @@ public class ProfileActivity extends BaseActivity {
});
boolean disableGif = sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_GIF), false);
String targetedUrl = disableGif ? account.avatar_static : account.avatar;
// MastodonHelper.loadPPMastodon(binding.accountPp, account);
Glide.with(ProfileActivity.this)
.asDrawable()
.dontTransform()
@ -271,6 +273,11 @@ public class ProfileActivity extends BaseActivity {
public void onResourceReady(@NonNull final Drawable resource, Transition<? super Drawable> transition) {
binding.profilePicture.setImageDrawable(resource);
binding.accountPp.setImageDrawable(resource);
if (resource instanceof Animatable) {
binding.profilePicture.animate();
binding.accountPp.animate();
((Animatable) resource).start();
}
ActivityCompat.startPostponedEnterTransition(ProfileActivity.this);
}
@ -390,7 +397,7 @@ public class ProfileActivity extends BaseActivity {
TextView.BufferType.SPANNABLE);
binding.accountNote.setMovementMethod(LinkMovementMethod.getInstance());
//MastodonHelper.loadPPMastodon(binding.accountPp, account);
binding.accountPp.setOnClickListener(v -> {
Intent intent = new Intent(ProfileActivity.this, MediaActivity.class);
Bundle b = new Bundle();
@ -935,13 +942,11 @@ public class ProfileActivity extends BaseActivity {
builderInner.setTitle(stringArrayConf[0]);
builderInner.setNeutralButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builderInner.setNegativeButton(R.string.keep_notifications, (dialog, which) -> {
accountsVM.mute(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, target, false, 0)
.observe(ProfileActivity.this, relationShip -> {
this.relationship = relationShip;
updateAccount();
});
});
builderInner.setNegativeButton(R.string.keep_notifications, (dialog, which) -> accountsVM.mute(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, target, false, 0)
.observe(ProfileActivity.this, relationShip -> {
this.relationship = relationShip;
updateAccount();
}));
builderInner.setPositiveButton(R.string.action_mute, (dialog, which) -> {
accountsVM.mute(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, target, true, 0)
.observe(ProfileActivity.this, relationShip -> {

View file

@ -130,9 +130,10 @@ public class SearchResultTabActivity extends BaseBarActivity {
search = query.trim();
ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
binding.searchViewpager.setAdapter(mPagerAdapter);
searchView.clearFocus();
setTitle(search);
searchView.setIconified(true);
searchView.setQuery(search, false);
searchView.clearFocus();
binding.searchTabLayout.selectTab(initial);
return false;
}

View file

@ -36,6 +36,7 @@ class SettingsActivity : BaseBarActivity() {
val navController = findNavController(R.id.fragment_container)
appBarConfiguration = AppBarConfiguration.Builder().build()
setupActionBarWithNavController(navController, appBarConfiguration)
}

View file

@ -85,7 +85,7 @@ public class Account implements Serializable {
if (display_name == null || display_name.isEmpty()) {
display_name = username;
}
return SpannableHelper.convert(context, display_name, null, this, null, false, viewWeakReference);
return SpannableHelper.convert(context, display_name, null, this, null, false, false, viewWeakReference);
}
public synchronized Spannable getSpanDisplayName(Activity activity, WeakReference<View> viewWeakReference) {
@ -96,11 +96,11 @@ public class Account implements Serializable {
}
public synchronized Spannable getSpanDisplayNameTitle(Context context, WeakReference<View> viewWeakReference, String title) {
return SpannableHelper.convert(context, title, null, this, null, false, viewWeakReference);
return SpannableHelper.convert(context, title, null, this, null, false, false, viewWeakReference);
}
public synchronized Spannable getSpanNote(Context context, WeakReference<View> viewWeakReference) {
return SpannableHelper.convert(context, note, null, this, null, true, viewWeakReference);
return SpannableHelper.convert(context, note, null, this, null, true, true, viewWeakReference);
}
public static class AccountParams implements Serializable {

View file

@ -56,7 +56,7 @@ public class Announcement {
public synchronized Spannable getSpanContent(Context context, WeakReference<View> viewWeakReference) {
return SpannableHelper.convert(context, content, null, null, this, true, viewWeakReference);
return SpannableHelper.convert(context, content, null, null, this, true, false, viewWeakReference);
}
}

View file

@ -51,6 +51,8 @@ public class Attachment implements Serializable {
public String focus = null;
public String translation = null;
public float measuredWidth = -1.f;
public static class Meta implements Serializable {
@SerializedName("focus")
public Focus focus;

View file

@ -47,7 +47,7 @@ public class Field implements Serializable {
if (verified_at != null && value != null) {
value_span = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.verified_text));
}
Spannable spannable = SpannableHelper.convert(context, value, null, account, null, true, viewWeakReference);
Spannable spannable = SpannableHelper.convert(context, value, null, account, null, true, true, viewWeakReference);
if (value_span != null && spannable != null) {
spannable.setSpan(value_span, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
@ -57,7 +57,7 @@ public class Field implements Serializable {
public synchronized Spannable getLabelSpan(Context context, Account account, WeakReference<View> viewWeakReference) {
Spannable spannable = SpannableHelper.convert(context, name, null, account, null, true, viewWeakReference);
Spannable spannable = SpannableHelper.convert(context, name, null, account, null, true, true, viewWeakReference);
if (name_span != null && spannable != null) {
spannable.setSpan(name_span, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

View file

@ -61,7 +61,7 @@ public class Poll implements Serializable {
public transient Spannable span_title;
public Spannable getSpanTitle(Context context, Status status, WeakReference<View> viewWeakReference) {
span_title = SpannableHelper.convert(context, title, status, null, null, false, viewWeakReference);
span_title = SpannableHelper.convert(context, title, status, null, null, false, false, viewWeakReference);
return span_title;
}
}

View file

@ -115,6 +115,10 @@ public class Status implements Serializable, Cloneable {
public transient boolean submitted = false;
public transient boolean spoilerChecked = false;
public Filter filteredByApp;
public transient Spannable contentSpan;
public transient Spannable contentSpoilerSpan;
public transient Spannable contentTranslateSpan;
@Override
public boolean equals(@Nullable Object obj) {
boolean same = false;
@ -124,17 +128,29 @@ public class Status implements Serializable, Cloneable {
return same;
}
public synchronized Spannable getSpanContent(Context context, WeakReference<View> viewWeakReference) {
return SpannableHelper.convert(context, content, this, null, null, true, viewWeakReference);
public synchronized Spannable getSpanContent(Context context, WeakReference<View> viewWeakReference, Callback callback) {
if (contentSpan == null) {
contentSpan = SpannableHelper.convert(context, content, this, null, null, true, false, viewWeakReference, callback);
}
return contentSpan;
}
public synchronized Spannable getSpanSpoiler(Context context, WeakReference<View> viewWeakReference) {
return SpannableHelper.convert(context, spoiler_text, this, null, null, true, viewWeakReference);
public synchronized Spannable getSpanSpoiler(Context context, WeakReference<View> viewWeakReference, Callback callback) {
if (contentSpoilerSpan == null) {
contentSpoilerSpan = SpannableHelper.convert(context, spoiler_text, this, null, null, true, false, viewWeakReference, callback);
}
return contentSpoilerSpan;
}
public synchronized Spannable getSpanTranslate(Context context, WeakReference<View> viewWeakReference) {
return SpannableHelper.convert(context, translationContent, this, null, null, true, viewWeakReference);
public synchronized Spannable getSpanTranslate(Context context, WeakReference<View> viewWeakReference, Callback callback) {
if (contentTranslateSpan == null) {
contentTranslateSpan = SpannableHelper.convert(context, translationContent, this, null, null, true, false, viewWeakReference, callback);
}
return contentTranslateSpan;
}
public interface Callback {
void emojiFetched();
}
@NonNull

View file

@ -6,6 +6,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.style.ReplacementSpan;
import android.view.View;
@ -13,26 +14,53 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.Emoji;
import app.fedilab.android.client.entities.api.Status;
public class CustomEmoji extends ReplacementSpan {
private final float scale;
private final WeakReference<View> viewWeakReference;
private Drawable imageDrawable;
private boolean callbackCalled;
CustomEmoji(WeakReference<View> viewWeakReference) {
Context mContext = viewWeakReference.get().getContext();
this.viewWeakReference = viewWeakReference;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
scale = sharedpreferences.getFloat(mContext.getString(R.string.SET_FONT_SCALE), 1.1f);
callbackCalled = false;
}
public SpannableStringBuilder makeEmoji(SpannableStringBuilder content, List<Emoji> emojiList, boolean animate, Status.Callback callback) {
if (emojiList != null && emojiList.size() > 0) {
int count = 1;
for (Emoji emoji : emojiList) {
Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
.matcher(content);
while (matcher.find()) {
CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(viewWeakReference.get()));
content.setSpan(customEmoji, matcher.start(), matcher.end(), 0);
Glide.with(viewWeakReference.get())
.asDrawable()
.load(animate ? emoji.url : emoji.static_url)
.into(customEmoji.getTarget(animate, count == emojiList.size() && !callbackCalled ? callback : null));
}
count++;
}
}
return content;
}
@Override
@ -61,7 +89,7 @@ public class CustomEmoji extends ReplacementSpan {
}
}
public Target<Drawable> getTarget(boolean animate) {
public Target<Drawable> getTarget(boolean animate, Status.Callback callback) {
return new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
@ -97,6 +125,10 @@ public class CustomEmoji extends ReplacementSpan {
if (view != null) {
view.invalidate();
}
if (callback != null && !callbackCalled) {
callbackCalled = true;
callback.emojiFetched();
}
}
@Override

View file

@ -323,7 +323,7 @@ public class Helper {
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);*/
public static final Pattern hashtagPattern = Pattern.compile("(#[\\w_A-zÀ-ÿ]+)");
public static final Pattern hashtagPattern = Pattern.compile("(^|\\s+|[.,;?!-]+)(#[\\w_A-zÀ-ÿ]+)");
public static final Pattern groupPattern = Pattern.compile("(![\\w_]+)");
public static final Pattern mentionPattern = Pattern.compile("(@[\\w_.-]+[\\w])");
public static final Pattern mentionLongPattern = Pattern.compile("(@[\\w_.-]+@[a-zA-Z0-9][a-zA-Z0-9.-]{1,61}[a-zA-Z0-9](?:\\.[a-zA-Z]{2,})+)");
@ -1918,6 +1918,8 @@ public class Helper {
return R.style.SolarizedAlertDialog;
} else if (R.style.BlackAppThemeBar == currentThemeId || R.style.BlackAppTheme == currentThemeId) {
return R.style.BlackAlertDialog;
} else if (R.style.DraculaAppThemeBar == currentThemeId || R.style.DraculaAppTheme == currentThemeId) {
return R.style.DraculaAlertDialog;
}
return R.style.AppTheme;
}

View file

@ -24,6 +24,7 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -40,7 +41,6 @@ import android.text.style.URLSpan;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.URLUtil;
import android.widget.Toast;
import androidx.annotation.NonNull;
@ -91,10 +91,38 @@ public class SpannableHelper {
public static Spannable convert(Context context, String text,
Status status, Account account, Announcement announcement,
boolean convertHtml,
WeakReference<View> viewWeakReference) {
boolean convertHtml, boolean forceMentions, WeakReference<View> viewWeakReference) {
return convert(context, text, status, account, announcement, convertHtml, forceMentions, viewWeakReference, null);
}
private static int linkColor;
public static Spannable convert(Context context, String text,
Status status, Account account, Announcement announcement,
boolean convertHtml,
boolean forceMentions,
WeakReference<View> viewWeakReference, Status.Callback callback) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
boolean customLight = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_LIGHT_COLORS), false);
boolean customDark = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_DARK_COLORS), false);
int link_color;
if (currentNightMode == Configuration.UI_MODE_NIGHT_NO && customLight) {
link_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_LINK), -1);
if (link_color != -1) {
linkColor = link_color;
}
} else if (currentNightMode == Configuration.UI_MODE_NIGHT_YES && customDark) {
link_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_LINK), -1);
if (link_color != -1) {
linkColor = link_color;
}
} else {
linkColor = ThemeHelper.getAttColor(context, R.attr.linkColor);
}
SpannableString initialContent;
if (text == null) {
return null;
@ -123,6 +151,7 @@ public class SpannableHelper {
} else if (announcement != null) {
emojiList = announcement.emojis;
}
//UrlDetails will contain links having a text different from the url
HashMap<String, String> urlDetails = new HashMap<>();
if (convertHtml) {
Matcher matcherALink = Helper.aLink.matcher(text);
@ -134,7 +163,7 @@ public class SpannableHelper {
if (urlText != null && urlText.startsWith(">")) {
urlText = urlText.substring(1);
}
if (url != null && urlText != null && !url.equals(urlText) && !urlText.contains("<span")) {
if (url != null && urlText != null && !url.equalsIgnoreCase(urlText) && !urlText.contains("<span")) {
urlDetails.put(url, urlText);
}
}
@ -149,7 +178,7 @@ public class SpannableHelper {
content.removeSpan(span);
}
//Make tags, mentions, groups
interaction(context, content, status, mentionList);
interaction(context, content, status, mentionList, forceMentions);
//Make all links
linkify(context, content, urlDetails);
linkifyURL(context, content, urlDetails);
@ -159,22 +188,9 @@ public class SpannableHelper {
} else {
content = new SpannableStringBuilder(text);
}
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false);
if (emojiList != null && emojiList.size() > 0) {
for (Emoji emoji : emojiList) {
Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
.matcher(content);
while (matcher.find()) {
CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(view));
content.setSpan(customEmoji, matcher.start(), matcher.end(), 0);
Glide.with(view)
.asDrawable()
.load(animate ? emoji.url : emoji.static_url)
.into(customEmoji.getTarget(animate));
}
}
}
CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(view));
content = customEmoji.makeEmoji(content, emojiList, animate, callback);
if (imagesToReplace.size() > 0) {
for (Map.Entry<String, String> entry : imagesToReplace.entrySet()) {
@ -183,12 +199,11 @@ public class SpannableHelper {
Matcher matcher = Pattern.compile(key, Pattern.LITERAL)
.matcher(content);
while (matcher.find()) {
CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(view));
content.setSpan(customEmoji, matcher.start(), matcher.end(), 0);
Glide.with(view)
.asDrawable()
.load(url)
.into(customEmoji.getTarget(animate));
.into(customEmoji.getTarget(animate, null));
}
}
@ -216,16 +231,15 @@ public class SpannableHelper {
final String url = content.toString().substring(matchStart, matchEnd);
if (urlDetails.containsKey(url)) {
continue;
}
String newURL = Helper.transformURL(context, url);
//If URL has been transformed
if (newURL.compareTo(url) != 0) {
content.replace(matchStart, matchEnd, newURL);
offSetTruncate -= (newURL.length() - url.length());
matchEnd = matchStart + newURL.length();
//The transformed URL was in the list of URLs having a different names
if (urlDetails.containsKey(url)) {
urlDetails.put(newURL, urlDetails.get(url));
}
}
//Truncate URL if needed
@ -237,14 +251,7 @@ public class SpannableHelper {
content.replace(matchStart, matchEnd, urlText);
matchEnd = matchStart + 31;
offSetTruncate += (newURL.length() - urlText.length());
} /*else if (urlDetails.containsKey(urlText) && urlDetails.get(urlText) != null) {
urlText = urlDetails.get(urlText);
if (urlText != null) {
content.replace(matchStart, matchEnd, urlText);
matchEnd = matchStart + urlText.length();
offSetTruncate += (newURL.length() - urlText.length());
}
}*/
}
if (matchEnd <= content.length() && matchEnd >= matchStart) {
@ -336,7 +343,7 @@ public class SpannableHelper {
}
}
httpsURLConnection.getInputStream().close();
if (redirect != null && finalURl1 != null && redirect.compareTo(finalURl1) != 0) {
if (redirect != null && redirect.compareTo(finalURl1) != 0) {
URL redirectURL = new URL(redirect);
String host = redirectURL.getHost();
String protocol = redirectURL.getProtocol();
@ -446,6 +453,12 @@ public class SpannableHelper {
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(linkColor);
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
@ -455,7 +468,7 @@ public class SpannableHelper {
for (Map.Entry<String, String> entry : urlDetails.entrySet()) {
String value = entry.getValue();
if (value.startsWith("@") || value.startsWith("#") || !URLUtil.isValidUrl(value)) {
if (value.startsWith("@") || value.startsWith("#")) {
continue;
}
SpannableString contentUrl;
@ -464,7 +477,7 @@ public class SpannableHelper {
else
contentUrl = new SpannableString(Html.fromHtml(value));
Pattern word = Pattern.compile(contentUrl.toString());
Pattern word = Pattern.compile(Pattern.quote(contentUrl.toString()));
Matcher matcherLink = word.matcher(content);
while (matcherLink.find()) {
String url = entry.getKey();
@ -668,6 +681,7 @@ public class SpannableHelper {
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(linkColor);
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
@ -701,6 +715,7 @@ public class SpannableHelper {
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(linkColor);
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
@ -737,21 +752,22 @@ public class SpannableHelper {
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(linkColor);
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
}
private static void interaction(Context context, Spannable content, Status status, List<Mention> mentions) {
private static void interaction(Context context, Spannable content, Status status, List<Mention> mentions, boolean forceMentions) {
// --- For all patterns defined in Helper class ---
for (Map.Entry<Helper.PatternType, Pattern> entry : Helper.patternHashMap.entrySet()) {
Helper.PatternType patternType = entry.getKey();
Pattern pattern = entry.getValue();
Matcher matcher = pattern.matcher(content);
if (pattern == Helper.mentionPattern && mentions == null) {
if (pattern == Helper.mentionPattern && mentions == null && !forceMentions) {
continue;
} else if (pattern == Helper.mentionLongPattern && mentions == null) {
} else if (pattern == Helper.mentionLongPattern && mentions == null && !forceMentions) {
continue;
}
@ -884,6 +900,7 @@ public class SpannableHelper {
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(linkColor);
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
@ -1031,6 +1048,8 @@ public class SpannableHelper {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(linkColor);
}
},
startPosition, endPosition,
@ -1066,7 +1085,7 @@ public class SpannableHelper {
Glide.with(viewWeakReference.get())
.asDrawable()
.load(animate ? emoji.url : emoji.static_url)
.into(customEmoji.getTarget(animate));
.into(customEmoji.getTarget(animate, null));
}
}
}

View file

@ -68,6 +68,11 @@ public class AccountAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(AccountsVM.class);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
accountViewHolder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
accountViewHolder.binding.dividerCard.setVisibility(View.GONE);
}
accountViewHolder.binding.avatar.setOnClickListener(v -> {
Intent intent = new Intent(context, ProfileActivity.class);
Bundle b = new Bundle();
@ -78,6 +83,8 @@ public class AccountAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
// start the new activity
context.startActivity(intent, options.toBundle());
});
accountViewHolder.binding.followAction.setIconResource(R.drawable.ic_baseline_person_add_24);
if (account.relationShip != null) {

View file

@ -17,6 +17,7 @@ package app.fedilab.android.ui.drawer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -27,6 +28,7 @@ import androidx.core.app.ActivityOptionsCompat;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
@ -69,6 +71,14 @@ public class AccountFollowRequestAdapter extends RecyclerView.Adapter<RecyclerVi
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
Account account = accountList.get(position);
ViewHolderFollow holderFollow = (ViewHolderFollow) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holderFollow.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holderFollow.binding.dividerCard.setVisibility(View.GONE);
}
MastodonHelper.loadPPMastodon(holderFollow.binding.avatar, account);
holderFollow.binding.displayName.setText(account.display_name);
holderFollow.binding.username.setText(String.format("@%s", account.acct));

View file

@ -16,14 +16,17 @@ package app.fedilab.android.ui.drawer;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import java.lang.ref.WeakReference;
@ -35,6 +38,7 @@ import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.Account;
import app.fedilab.android.client.entities.api.MastodonList;
import app.fedilab.android.databinding.DrawerAccountListBinding;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.MastodonHelper;
import app.fedilab.android.helper.ThemeHelper;
import app.fedilab.android.viewmodel.mastodon.TimelinesVM;
@ -78,6 +82,12 @@ public class AccountListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
account = getItem(position);
AccountListViewHolder holder = (AccountListViewHolder) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
MastodonHelper.loadPPMastodon(holder.binding.avatar, account);
holder.binding.displayName.setText(
account.getSpanDisplayName(context,

View file

@ -19,6 +19,7 @@ import static android.content.Context.INPUT_METHOD_SERVICE;
import static app.fedilab.android.BaseMainActivity.emojis;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -30,6 +31,7 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -80,6 +82,14 @@ public class AnnouncementAdapter extends RecyclerView.Adapter<AnnouncementAdapte
@Override
public void onBindViewHolder(@NonNull AnnouncementHolder holder, int position) {
Announcement announcement = announcements.get(position);
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
if (announcement.reactions != null && announcement.reactions.size() > 0) {
ReactionAdapter reactionAdapter = new ReactionAdapter(announcement.id, announcement.reactions);
holder.binding.layoutReactions.reactionsView.setAdapter(reactionAdapter);

View file

@ -725,6 +725,13 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
}
if (emojis == null) {
return;
} else if (emojisList == null) {
if (emojis.containsKey(BaseMainActivity.currentInstance)) {
emojisList = emojis.get(BaseMainActivity.currentInstance);
}
}
if (emojisList == null) {
return;
}
for (Emoji emoji : emojisList) {
if (shortcode != null && emoji.shortcode.contains(shortcode)) {
@ -1107,7 +1114,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
StatusSimpleViewHolder holder = (StatusSimpleViewHolder) viewHolder;
holder.binding.statusContent.setText(
status.getSpanContent(context,
new WeakReference<>(holder.binding.statusContent)),
new WeakReference<>(holder.binding.statusContent), null),
TextView.BufferType.SPANNABLE);
MastodonHelper.loadPPMastodon(holder.binding.avatar, status.account);
if (status.account != null) {
@ -1122,7 +1129,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
holder.binding.spoiler.setVisibility(View.VISIBLE);
holder.binding.spoiler.setText(
status.getSpanSpoiler(context,
new WeakReference<>(holder.binding.spoiler)),
new WeakReference<>(holder.binding.spoiler), null),
TextView.BufferType.SPANNABLE);
} else {
holder.binding.spoiler.setVisibility(View.GONE);

View file

@ -19,6 +19,7 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
@ -83,14 +84,56 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
return new ConversationHolder(itemBinding);
}
public static void applyColorConversation(Context context, ConversationHolder holder) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
boolean customLight = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_LIGHT_COLORS), false);
boolean customDark = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_DARK_COLORS), false);
int theme_icons_color = -1;
int theme_statuses_color = -1;
int theme_text_color = -1;
if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { //LIGHT THEME
if (customLight) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_ICON), -1);
theme_statuses_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_BACKGROUND), -1);
theme_text_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_TEXT), -1);
}
} else {
if (customDark) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_ICON), -1);
theme_statuses_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_BACKGROUND), -1);
theme_text_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_TEXT), -1);
}
}
if (theme_icons_color != -1) {
Helper.changeDrawableColor(context, R.drawable.ic_star_outline, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_person, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_bot, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_baseline_reply_16, theme_icons_color);
}
if (theme_statuses_color != -1) {
holder.binding.cardviewContainer.setBackgroundColor(theme_statuses_color);
}
if (theme_text_color != -1) {
holder.binding.statusContent.setTextColor(theme_text_color);
holder.binding.spoiler.setTextColor(theme_text_color);
Helper.changeDrawableColor(context, R.drawable.ic_baseline_lock_24, theme_text_color);
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
Conversation conversation = conversationList.get(position);
ConversationHolder holder = (ConversationHolder) viewHolder;
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
//--- Profile Pictures for participants ---
holder.binding.participantsList.removeAllViews();
@ -151,7 +194,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
holder.binding.spoiler.setVisibility(View.VISIBLE);
holder.binding.spoiler.setText(
conversation.last_status.getSpanSpoiler(context,
new WeakReference<>(holder.binding.spoiler)),
new WeakReference<>(holder.binding.spoiler), () -> notifyItemChanged(holder.getBindingAdapterPosition())),
TextView.BufferType.SPANNABLE);
} else {
holder.binding.spoiler.setVisibility(View.GONE);
@ -161,7 +204,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
//--- MAIN CONTENT ---
holder.binding.statusContent.setText(
conversation.last_status.getSpanContent(context,
new WeakReference<>(holder.binding.statusContent)),
new WeakReference<>(holder.binding.statusContent), () -> notifyItemChanged(holder.getBindingAdapterPosition())),
TextView.BufferType.SPANNABLE);
//--- DATE ---
holder.binding.lastMessageDate.setText(Helper.dateDiff(context, conversation.last_status.created_at));
@ -198,6 +241,8 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
}, 100, 100);
}
applyColorConversation(context, holder);
}
private void displayAttachments(ConversationAdapter.ConversationHolder holder, int position) {

View file

@ -15,13 +15,16 @@ package app.fedilab.android.ui.drawer;
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
@ -61,6 +64,13 @@ public class DomainBlockAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
String domain = domainList.get(position);
DomainBlockViewHolder holder = (DomainBlockViewHolder) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
holder.binding.domainName.setText(domain);
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(AccountsVM.class);
holder.binding.unblockDomain.setOnClickListener(v -> {

View file

@ -16,11 +16,13 @@ package app.fedilab.android.ui.drawer;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
@ -46,6 +48,11 @@ public class InstanceRegAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
JoinMastodonInstance joinMastodonInstance = joinMastodonInstanceList.get(position);
ViewHolder holder = (ViewHolder) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
holder.binding.instanceCountUser.setText(context.getString(R.string.users, Helper.withSuffix(joinMastodonInstance.total_users)));
holder.binding.instanceDescription.setText(joinMastodonInstance.description);
holder.binding.instanceHost.setText(joinMastodonInstance.domain);

View file

@ -21,6 +21,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -71,6 +72,7 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
private final int TYPE_ADMIN_REPORT = 12;
public FetchMoreCallBack fetchMoreCallBack;
private Context context;
private RecyclerView mRecyclerView;
public NotificationAdapter(List<Notification> notificationList) {
this.notificationList = notificationList;
@ -120,6 +122,13 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
return super.getItemViewType(position);
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
mRecyclerView = recyclerView;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@ -136,11 +145,60 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
}
public static void applyColorAccount(Context context, ViewHolderFollow holder) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
boolean customLight = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_LIGHT_COLORS), false);
boolean customDark = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_DARK_COLORS), false);
int theme_icons_color = -1;
int theme_statuses_color = -1;
int theme_text_color = -1;
int theme_text_header_1_line = -1;
int theme_text_header_2_line = -1;
if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { //LIGHT THEME
if (customLight) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_ICON), -1);
theme_statuses_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_BACKGROUND), -1);
theme_text_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_TEXT), -1);
theme_text_header_1_line = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_DISPLAY_NAME), -1);
theme_text_header_2_line = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_USERNAME), -1);
}
} else {
if (customDark) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_ICON), -1);
theme_statuses_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_BACKGROUND), -1);
theme_text_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_TEXT), -1);
theme_text_header_1_line = sharedpreferences.getInt(context.getString(R.string.SET_DARK_DISPLAY_NAME), -1);
theme_text_header_2_line = sharedpreferences.getInt(context.getString(R.string.SET_DARK_USERNAME), -1);
}
}
if (theme_text_color != -1) {
holder.binding.title.setTextColor(theme_text_color);
}
if (theme_icons_color != -1) {
Helper.changeDrawableColor(context, holder.binding.icon, theme_icons_color);
}
if (theme_statuses_color != -1) {
holder.binding.cardviewContainer.setBackgroundColor(theme_statuses_color);
}
if (theme_text_header_1_line != -1) {
holder.binding.displayName.setTextColor(theme_text_header_1_line);
}
if (theme_text_header_2_line != -1) {
holder.binding.username.setTextColor(theme_text_header_2_line);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
Notification notification = notificationList.get(position);
if (getItemViewType(position) == TYPE_FOLLOW || getItemViewType(position) == TYPE_FOLLOW_REQUEST || getItemViewType(position) == TYPE_ADMIN_REPORT || getItemViewType(position) == TYPE_ADMIN_SIGNUP) {
ViewHolderFollow holderFollow = (ViewHolderFollow) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holderFollow.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holderFollow.binding.dividerCard.setVisibility(View.GONE);
}
MastodonHelper.loadPPMastodon(holderFollow.binding.avatar, notification.account);
holderFollow.binding.displayName.setText(
notification.account.getSpanDisplayName(context,
@ -217,8 +275,10 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
} else {
holderFollow.binding.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE);
}
applyColorAccount(context, holderFollow);
} else if (getItemViewType(position) == TYPE_FILERED) {
StatusAdapter.StatusViewHolder holder = (StatusAdapter.StatusViewHolder) viewHolder;
holder.bindingFiltered.filteredText.setText(context.getString(R.string.filtered_by, notification.filteredByApp.title));
holder.bindingFiltered.displayButton.setOnClickListener(v -> {
notification.filteredByApp = null;
@ -226,6 +286,11 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
});
} else {
StatusAdapter.StatusViewHolder holderStatus = (StatusAdapter.StatusViewHolder) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holderStatus.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holderStatus.binding.dividerCard.setVisibility(View.GONE);
}
holderStatus.bindingNotification.status.typeOfNotification.setVisibility(View.VISIBLE);
if (getItemViewType(position) == TYPE_MENTION) {
@ -243,13 +308,30 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
} else if (getItemViewType(position) == TYPE_POLL) {
holderStatus.bindingNotification.status.typeOfNotification.setImageResource(R.drawable.ic_baseline_poll_24);
}
int theme_icons_color = -1;
int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
boolean customLight = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_LIGHT_COLORS), false);
boolean customDark = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_DARK_COLORS), false);
if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { //LIGHT THEME
if (customLight) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_ICON), -1);
}
} else {
if (customDark) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_ICON), -1);
}
}
if (theme_icons_color != -1) {
Helper.changeDrawableColor(context, holderStatus.bindingNotification.status.typeOfNotification, theme_icons_color);
}
holderStatus.bindingNotification.status.mainContainer.setAlpha(1.0f);
StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class);
SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class);
if (notification.status != null) {
notification.status.cached = notification.cached;
}
statusManagement(context, statusesVM, searchVM, holderStatus, this, null, notification.status, Timeline.TimeLineEnum.NOTIFICATION, false, true, false, null);
statusManagement(context, statusesVM, searchVM, holderStatus, mRecyclerView, this, null, notification.status, Timeline.TimeLineEnum.NOTIFICATION, false, true, false, null);
holderStatus.bindingNotification.status.dateShort.setText(Helper.dateDiff(context, notification.created_at));
if (getItemViewType(position) == TYPE_MENTION || getItemViewType(position) == TYPE_STATUS || getItemViewType(position) == TYPE_REACTION) {
@ -286,7 +368,6 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
} else {
holderStatus.bindingNotification.status.mainContainer.setAlpha(.7f);
holderStatus.bindingNotification.status.mainContainer.setVisibility(View.VISIBLE);
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
boolean displayMedia = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_MEDIA_NOTIFICATION), true);
if (displayMedia && notification.status != null && notification.status.media_attachments != null && notification.status.media_attachments.size() > 0) {
holderStatus.bindingNotification.status.mediaContainer.setVisibility(View.VISIBLE);
@ -362,6 +443,7 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
holderStatus.bindingNotification.status.username.setText(String.format("@%s", notification.account.acct));
holderStatus.bindingNotification.status.actionButtons.setVisibility(View.GONE);
}
StatusAdapter.applyColor(context, holderStatus);
}
}

View file

@ -36,6 +36,7 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
@ -123,6 +124,7 @@ import app.fedilab.android.client.entities.app.BaseAccount;
import app.fedilab.android.client.entities.app.StatusCache;
import app.fedilab.android.client.entities.app.StatusDraft;
import app.fedilab.android.client.entities.app.Timeline;
import app.fedilab.android.databinding.DrawerFetchMoreBinding;
import app.fedilab.android.databinding.DrawerStatusArtBinding;
import app.fedilab.android.databinding.DrawerStatusBinding;
import app.fedilab.android.databinding.DrawerStatusFilteredBinding;
@ -165,6 +167,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
public FetchMoreCallBack fetchMoreCallBack;
private Context context;
private RecyclerView mRecyclerView;
public StatusAdapter(List<Status> statuses, Timeline.TimeLineEnum timelineType, boolean minified, boolean canBeFederated, boolean checkRemotely) {
this.statusList = statuses;
this.timelineType = timelineType;
@ -173,6 +177,18 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
this.checkRemotely = checkRemotely;
}
public static int getStatusPosition(List<Status> timelineStatuses, Status status) {
int position = 0;
if (timelineStatuses != null && status != null) {
for (Status _s : timelineStatuses) {
if (_s.id.compareTo(status.id) == 0) {
return position;
}
position++;
}
}
return -1;
}
private static boolean isVisible(Timeline.TimeLineEnum timelineType, Status status) {
if (timelineType == Timeline.TimeLineEnum.HOME && !show_boosts && status.reblog != null) {
@ -355,6 +371,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
StatusesVM statusesVM,
SearchVM searchVM,
StatusViewHolder holder,
RecyclerView recyclerView,
RecyclerView.Adapter<RecyclerView.ViewHolder> adapter,
List<Status> statusList,
Status status,
@ -372,14 +389,12 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
boolean expand_cw = sharedpreferences.getBoolean(context.getString(R.string.SET_EXPAND_CW), false);
boolean expand_media = sharedpreferences.getBoolean(context.getString(R.string.SET_EXPAND_MEDIA), false);
boolean display_card = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_CARD), false);
boolean share_details = sharedpreferences.getBoolean(context.getString(R.string.SET_SHARE_DETAILS), true);
boolean confirmFav = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION_FAV), false);
boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true);
boolean fullAttachement = sharedpreferences.getBoolean(context.getString(R.string.SET_FULL_PREVIEW), false);
boolean displayBookmark = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_BOOKMARK), true);
boolean long_press_media = sharedpreferences.getBoolean(context.getString(R.string.SET_LONG_PRESS_STORE_MEDIA), false);
boolean displayCounters = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_COUNTER_FAV_BOOST), false);
String loadMediaType = sharedpreferences.getString(context.getString(R.string.SET_LOAD_MEDIA_TYPE), "ALWAYS");
@ -506,16 +521,19 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.actionButtonFavorite.pressOnTouch(false);
holder.binding.actionButtonBoost.pressOnTouch(false);
holder.binding.actionButtonBookmark.pressOnTouch(false);
holder.binding.actionButtonFavorite.setActiveImage(R.drawable.ic_baseline_star_24);
holder.binding.actionButtonFavorite.setInactiveImage(R.drawable.ic_star_outline);
holder.binding.actionButtonBookmark.setInactiveImage(R.drawable.ic_baseline_bookmark_border_24);
holder.binding.actionButtonFavorite.setActiveImage(R.drawable.ic_round_star_24);
holder.binding.actionButtonFavorite.setInactiveImage(R.drawable.ic_round_star_border_24);
holder.binding.actionButtonBookmark.setActiveImage(R.drawable.ic_round_bookmark_24);
holder.binding.actionButtonBookmark.setInactiveImage(R.drawable.ic_round_bookmark_border_24);
holder.binding.actionButtonBoost.setActiveImage(R.drawable.ic_round_repeat_24);
holder.binding.actionButtonBoost.setInactiveImage(R.drawable.ic_round_repeat_24);
holder.binding.actionButtonFavorite.setDisableCircle(true);
holder.binding.actionButtonBoost.setDisableCircle(true);
holder.binding.actionButtonBookmark.setDisableCircle(true);
holder.binding.actionButtonFavorite.setActiveImageTint(R.color.marked_icon);
holder.binding.actionButtonBoost.setActiveImageTint(R.color.boost_icon);
holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon);
applyColor(context, holder);
if (status.pinned) {
holder.binding.statusPinned.setVisibility(View.VISIBLE);
@ -865,13 +883,13 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
//Button sizes depending of the defined scale
float normalSize = Helper.convertDpToPixel(28, context);
float normalSize2 = Helper.convertDpToPixel(24, context);
holder.binding.actionButtonReply.getLayoutParams().width = (int) (normalSize * scaleIcon);
holder.binding.actionButtonReply.getLayoutParams().height = (int) (normalSize * scaleIcon);
holder.binding.actionButtonReply.requestLayout();
holder.binding.actionButtonBoost.setImageSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonFavorite.setImageSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonBookmark.setImageSize((int) (normalSize2 * scaleIcon));
holder.binding.actionButtonBookmark.setImageSize((int) (normalSize * scaleIcon));
holder.binding.statusAddCustomEmoji.getLayoutParams().width = (int) (normalSize * scaleIcon);
holder.binding.statusAddCustomEmoji.getLayoutParams().height = (int) (normalSize * scaleIcon);
@ -986,7 +1004,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.spoiler.setVisibility(View.VISIBLE);
holder.binding.spoiler.setText(
statusToDeal.getSpanSpoiler(context,
new WeakReference<>(holder.binding.spoiler)),
new WeakReference<>(holder.binding.spoiler), () -> recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))),
TextView.BufferType.SPANNABLE);
statusToDeal.isExpended = true;
statusToDeal.isMediaDisplayed = true;
@ -1001,7 +1019,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.spoiler.setText(
statusToDeal.getSpanSpoiler(context,
new WeakReference<>(holder.binding.spoiler)),
new WeakReference<>(holder.binding.spoiler), () -> recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))),
TextView.BufferType.SPANNABLE);
}
if (statusToDeal.isExpended) {
@ -1049,7 +1067,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
//--- MAIN CONTENT ---
holder.binding.statusContent.setText(
statusToDeal.getSpanContent(context,
new WeakReference<>(holder.binding.statusContent)),
new WeakReference<>(holder.binding.statusContent), () -> {
recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()));
}),
TextView.BufferType.SPANNABLE);
if (truncate_toots_size > 0) {
holder.binding.statusContent.setMaxLines(truncate_toots_size);
@ -1085,7 +1105,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.containerTrans.setVisibility(View.VISIBLE);
holder.binding.statusContentTranslated.setText(
statusToDeal.getSpanTranslate(context,
new WeakReference<>(holder.binding.statusContentTranslated)),
new WeakReference<>(holder.binding.statusContentTranslated), () -> {
recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()));
}),
TextView.BufferType.SPANNABLE);
} else {
holder.binding.containerTrans.setVisibility(View.GONE);
@ -1106,234 +1128,70 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
if (statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) {
holder.binding.attachmentsList.removeAllViews();
holder.binding.mediaContainer.removeAllViews();
//If only one attachment
if (statusToDeal.media_attachments.size() == 1) {
if ((loadMediaType.equals("ASK") || (loadMediaType.equals("WIFI") && !TimelineHelper.isOnWIFI(context))) && !statusToDeal.canLoadMedia) {
holder.binding.mediaContainer.setVisibility(View.GONE);
holder.binding.displayMedia.setVisibility(View.VISIBLE);
holder.binding.displayMedia.setOnClickListener(v -> {
statusToDeal.canLoadMedia = true;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
} else {
holder.binding.mediaContainer.setVisibility(View.VISIBLE);
holder.binding.displayMedia.setVisibility(View.GONE);
LayoutMediaBinding layoutMediaBinding = LayoutMediaBinding.inflate(LayoutInflater.from(context), holder.binding.attachmentsList, false);
LinearLayout.LayoutParams lp;
if ((loadMediaType.equals("ASK") || (loadMediaType.equals("WIFI") && !TimelineHelper.isOnWIFI(context))) && !statusToDeal.canLoadMedia) {
holder.binding.mediaContainer.setVisibility(View.GONE);
holder.binding.displayMedia.setVisibility(View.VISIBLE);
holder.binding.displayMedia.setOnClickListener(v -> {
statusToDeal.canLoadMedia = true;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
} else {
int mediaPosition = 1;
boolean singleMedia = statusToDeal.media_attachments.size() == 1;
for (Attachment attachment : statusToDeal.media_attachments) {
LayoutMediaBinding layoutMediaBinding = LayoutMediaBinding.inflate(LayoutInflater.from(context));
if (fullAttachement) {
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.FIT_CENTER);
} else {
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) Helper.convertDpToPixel(200, context));
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
if (statusToDeal.sensitive) {
Helper.changeDrawableColor(context, layoutMediaBinding.viewHide, ThemeHelper.getAttColor(context, R.attr.colorError));
} else {
Helper.changeDrawableColor(context, layoutMediaBinding.viewHide, R.color.white);
}
layoutMediaBinding.media.setLayoutParams(lp);
layoutMediaBinding.media.setOnClickListener(v -> {
if (statusToDeal.isMediaObfuscated && mediaObfuscated(statusToDeal) && !expand_media) {
statusToDeal.isMediaObfuscated = false;
int position = holder.getBindingAdapterPosition();
adapter.notifyItemChanged(position);
final int timeout = sharedpreferences.getInt(context.getString(R.string.SET_NSFW_TIMEOUT), 5);
float ratio = 1.0f;
float mediaH = -1.0f;
if (timeout > 0) {
new CountDownTimer((timeout * 1000L), 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
status.isMediaObfuscated = true;
adapter.notifyItemChanged(position);
}
}.start();
if (attachment.measuredWidth > 0) {
if (attachment.meta != null && attachment.meta.small != null) {
float viewWidth = attachment.measuredWidth;
mediaH = attachment.meta.small.height;
float mediaW = attachment.meta.small.width;
if (mediaW != 0) {
ratio = viewWidth / mediaW;
}
}
return;
loadAndAddAttachment(context, layoutMediaBinding, holder, adapter, mediaPosition, mediaH, ratio, statusToDeal, attachment, singleMedia);
} else {
int finalMediaPosition = mediaPosition;
layoutMediaBinding.media.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
layoutMediaBinding.media.getViewTreeObserver().removeOnGlobalLayoutListener(this);
attachment.measuredWidth = layoutMediaBinding.media.getWidth();
float ratio = 1.0f;
float mediaH = -1.0f;
if (attachment.meta != null && attachment.meta.small != null) {
float viewWidth = attachment.measuredWidth;
mediaH = attachment.meta.small.height;
float mediaW = attachment.meta.small.width;
if (mediaW != 0) {
ratio = viewWidth / mediaW;
}
}
loadAndAddAttachment(context, layoutMediaBinding, holder, adapter, finalMediaPosition, mediaH, ratio, statusToDeal, attachment, singleMedia);
}
});
}
Intent mediaIntent = new Intent(context, MediaActivity.class);
Bundle b = new Bundle();
b.putInt(Helper.ARG_MEDIA_POSITION, 1);
b.putSerializable(Helper.ARG_MEDIA_ARRAY, new ArrayList<>(statusToDeal.media_attachments));
mediaIntent.putExtras(b);
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, layoutMediaBinding.media, statusToDeal.media_attachments.get(0).url);
// start the new activity
context.startActivity(mediaIntent, options.toBundle());
});
if (statusToDeal.media_attachments.get(0).type != null && (statusToDeal.media_attachments.get(0).type.equalsIgnoreCase("video") || statusToDeal.media_attachments.get(0).type.equalsIgnoreCase("gifv"))) {
layoutMediaBinding.playVideo.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.playVideo.setVisibility(View.GONE);
loadAndAddAttachment(context, layoutMediaBinding, holder, adapter, mediaPosition, -1.f, -1.f, statusToDeal, attachment, singleMedia);
}
if (statusToDeal.media_attachments.get(0).type != null && statusToDeal.media_attachments.get(0).type.equalsIgnoreCase("audio")) {
layoutMediaBinding.playMusic.setVisibility(View.VISIBLE);
mediaPosition++;
if (fullAttachement || singleMedia) {
holder.binding.mediaContainer.addView(layoutMediaBinding.getRoot());
} else {
layoutMediaBinding.playMusic.setVisibility(View.GONE);
holder.binding.attachmentsList.addView(layoutMediaBinding.getRoot());
}
String finalUrl;
if (statusToDeal.media_attachments.get(0).url == null) {
finalUrl = statusToDeal.media_attachments.get(0).remote_url;
} else {
finalUrl = statusToDeal.media_attachments.get(0).url;
}
layoutMediaBinding.media.setOnLongClickListener(v -> {
if (long_press_media) {
MediaHelper.manageMove(context, finalUrl, false);
}
return true;
});
float focusX = 0.f;
float focusY = 0.f;
if (statusToDeal.media_attachments.get(0).meta != null && statusToDeal.media_attachments.get(0).meta.focus != null) {
focusX = statusToDeal.media_attachments.get(0).meta.focus.x;
focusY = statusToDeal.media_attachments.get(0).meta.focus.y;
}
if (statusToDeal.media_attachments.get(0).description != null && !statusToDeal.media_attachments.get(0).description.isEmpty()) {
layoutMediaBinding.viewDescription.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.viewDescription.setVisibility(View.GONE);
}
if (!mediaObfuscated(statusToDeal) || expand_media) {
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_24);
RequestBuilder<Drawable> requestBuilder = Glide.with(layoutMediaBinding.media.getContext())
.load(statusToDeal.media_attachments.get(0).preview_url);
if (!fullAttachement) {
requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY)));
}
requestBuilder.into(layoutMediaBinding.media);
} else {
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_off_24);
Glide.with(layoutMediaBinding.media.getContext())
.load(statusToDeal.media_attachments.get(0).preview_url)
.apply(new RequestOptions().transform(new BlurTransformation(50, 3)))
// .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners((int) Helper.convertDpToPixel(3, context))))
.into(layoutMediaBinding.media);
}
layoutMediaBinding.viewHide.setOnClickListener(v -> {
statusToDeal.sensitive = !statusToDeal.sensitive;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
holder.binding.mediaContainer.addView(layoutMediaBinding.getRoot());
}
if (!fullAttachement && !singleMedia) {
holder.binding.mediaContainer.setVisibility(View.GONE);
holder.binding.attachmentsListContainer.setVisibility(View.VISIBLE);
} else {
holder.binding.mediaContainer.setVisibility(View.VISIBLE);
holder.binding.attachmentsListContainer.setVisibility(View.GONE);
}
} else { //Several media
if ((loadMediaType.equals("ASK") || (loadMediaType.equals("WIFI") && !TimelineHelper.isOnWIFI(context))) && !statusToDeal.canLoadMedia) {
holder.binding.mediaContainer.setVisibility(View.GONE);
holder.binding.displayMedia.setVisibility(View.VISIBLE);
holder.binding.displayMedia.setOnClickListener(v -> {
statusToDeal.canLoadMedia = true;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
} else {
int mediaPosition = 1;
for (Attachment attachment : statusToDeal.media_attachments) {
LayoutMediaBinding layoutMediaBinding = LayoutMediaBinding.inflate(LayoutInflater.from(context), holder.binding.attachmentsList, false);
LinearLayout.LayoutParams lp;
float focusX = 0.f;
float focusY = 0.f;
if (statusToDeal.media_attachments.get(0).meta != null && statusToDeal.media_attachments.get(0).meta.focus != null) {
focusX = statusToDeal.media_attachments.get(0).meta.focus.x;
focusY = statusToDeal.media_attachments.get(0).meta.focus.y;
}
layoutMediaBinding.count.setVisibility(View.VISIBLE);
if (!fullAttachement) {
layoutMediaBinding.count.setText(String.format(Locale.getDefault(), "%d/%d", mediaPosition, statusToDeal.media_attachments.size()));
}
String finalUrl;
if (attachment.url == null) {
finalUrl = attachment.remote_url;
} else {
finalUrl = attachment.url;
}
layoutMediaBinding.media.setOnLongClickListener(v -> {
if (long_press_media) {
MediaHelper.manageMove(context, finalUrl, false);
}
return true;
});
if (fullAttachement) {
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.FIT_CENTER);
} else {
lp = new LinearLayout.LayoutParams((int) Helper.convertDpToPixel(200, context), (int) Helper.convertDpToPixel(200, context));
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
if (attachment.type != null && (attachment.type.equalsIgnoreCase("video") || attachment.type.equalsIgnoreCase("gifv"))) {
layoutMediaBinding.playVideo.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.playVideo.setVisibility(View.GONE);
}
if (attachment.type != null && attachment.type.equalsIgnoreCase("audio")) {
layoutMediaBinding.playMusic.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.playMusic.setVisibility(View.GONE);
}
if (attachment.description != null && !attachment.description.isEmpty()) {
layoutMediaBinding.viewDescription.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.viewDescription.setVisibility(View.GONE);
}
if (!mediaObfuscated(statusToDeal) || expand_media) {
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_24);
RequestBuilder<Drawable> requestBuilder = Glide.with(layoutMediaBinding.media.getContext())
.load(attachment.preview_url);
if (!fullAttachement) {
requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY)));
}
requestBuilder.into(layoutMediaBinding.media);
} else {
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_off_24);
Glide.with(layoutMediaBinding.media.getContext())
.load(attachment.preview_url)
.apply(new RequestOptions().transform(new BlurTransformation(50, 3)))
// .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners((int) Helper.convertDpToPixel(3, context))))
.into(layoutMediaBinding.media);
}
if (statusToDeal.sensitive) {
Helper.changeDrawableColor(context, layoutMediaBinding.viewHide, ThemeHelper.getAttColor(context, R.attr.colorError));
} else {
Helper.changeDrawableColor(context, layoutMediaBinding.viewHide, R.color.white);
}
layoutMediaBinding.media.setLayoutParams(lp);
int finalMediaPosition = mediaPosition;
layoutMediaBinding.media.setOnClickListener(v -> {
Intent mediaIntent = new Intent(context, MediaActivity.class);
Bundle b = new Bundle();
b.putInt(Helper.ARG_MEDIA_POSITION, finalMediaPosition);
b.putSerializable(Helper.ARG_MEDIA_ARRAY, new ArrayList<>(statusToDeal.media_attachments));
mediaIntent.putExtras(b);
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, layoutMediaBinding.media, statusToDeal.media_attachments.get(finalMediaPosition - 1).url);
// start the new activity
context.startActivity(mediaIntent, options.toBundle());
});
layoutMediaBinding.viewHide.setOnClickListener(v -> {
statusToDeal.sensitive = !statusToDeal.sensitive;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
if (fullAttachement) {
layoutMediaBinding.getRoot().setPadding(0, 0, 0, 10);
holder.binding.mediaContainer.addView(layoutMediaBinding.getRoot());
} else {
layoutMediaBinding.getRoot().setPadding(0, 0, 10, 0);
holder.binding.attachmentsList.addView(layoutMediaBinding.getRoot());
}
mediaPosition++;
}
if (!fullAttachement) {
holder.binding.mediaContainer.setVisibility(View.GONE);
holder.binding.attachmentsListContainer.setVisibility(View.VISIBLE);
} else {
holder.binding.mediaContainer.setVisibility(View.VISIBLE);
holder.binding.attachmentsListContainer.setVisibility(View.GONE);
}
}
}
} else {
holder.binding.displayMedia.setVisibility(View.GONE);
@ -2012,21 +1870,34 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
if (status.isFetchMore && fetchMoreCallBack != null) {
holder.binding.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE);
holder.binding.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> {
DrawerFetchMoreBinding drawerFetchMoreBinding = DrawerFetchMoreBinding.inflate(LayoutInflater.from(context));
if (status.positionFetchMore == Status.PositionFetchMore.BOTTOM) {
holder.binding.fetchMoreContainerBottom.setVisibility(View.GONE);
holder.binding.fetchMoreContainerTop.setVisibility(View.VISIBLE);
holder.binding.fetchMoreContainerTop.removeAllViews();
holder.binding.fetchMoreContainerTop.addView(drawerFetchMoreBinding.getRoot());
} else {
holder.binding.fetchMoreContainerBottom.setVisibility(View.VISIBLE);
holder.binding.fetchMoreContainerTop.setVisibility(View.GONE);
holder.binding.fetchMoreContainerBottom.removeAllViews();
holder.binding.fetchMoreContainerBottom.addView(drawerFetchMoreBinding.getRoot());
}
drawerFetchMoreBinding.fetchMoreMin.setOnClickListener(v -> {
status.isFetchMore = false;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
if (holder.getBindingAdapterPosition() < statusList.size() - 1) {
int position = holder.getBindingAdapterPosition();
int position2 = getStatusPosition(statusList, status);
adapter.notifyItemChanged(position);
if (position < statusList.size() - 1) {
String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
fromId = statusList.get(holder.getBindingAdapterPosition() + 1).id;
fromId = statusList.get(position + 1).id;
} else {
fromId = status.id;
}
fetchMoreCallBack.onClickMinId(fromId, status);
}
});
holder.binding.layoutFetchMore.fetchMoreMax.setOnClickListener(v -> {
drawerFetchMoreBinding.fetchMoreMax.setOnClickListener(v -> {
//We hide the button
status.isFetchMore = false;
String fromId;
@ -2039,11 +1910,153 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
} else {
holder.binding.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE);
holder.binding.fetchMoreContainerBottom.setVisibility(View.GONE);
holder.binding.fetchMoreContainerTop.setVisibility(View.GONE);
}
}
private static void loadAndAddAttachment(Context context, LayoutMediaBinding layoutMediaBinding,
StatusViewHolder holder,
RecyclerView.Adapter<RecyclerView.ViewHolder> adapter,
int mediaPosition, float mediaH, float ratio,
Status statusToDeal, Attachment attachment, boolean singleImage) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
final int timeout = sharedpreferences.getInt(context.getString(R.string.SET_NSFW_TIMEOUT), 5);
boolean fullAttachement = sharedpreferences.getBoolean(context.getString(R.string.SET_FULL_PREVIEW), false);
boolean long_press_media = sharedpreferences.getBoolean(context.getString(R.string.SET_LONG_PRESS_STORE_MEDIA), false);
boolean expand_media = sharedpreferences.getBoolean(context.getString(R.string.SET_EXPAND_MEDIA), false);
LinearLayout.LayoutParams lp;
if (fullAttachement && mediaH > 0) {
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (mediaH * ratio));
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.FIT_CENTER);
} else {
if (singleImage) {
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) Helper.convertDpToPixel(200, context));
} else {
lp = new LinearLayout.LayoutParams((int) Helper.convertDpToPixel(200, context), (int) Helper.convertDpToPixel(200, context));
}
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
layoutMediaBinding.media.setLayoutParams(lp);
float focusX = 0.f;
float focusY = 0.f;
if (statusToDeal.media_attachments.get(0).meta != null && statusToDeal.media_attachments.get(0).meta.focus != null) {
focusX = statusToDeal.media_attachments.get(0).meta.focus.x;
focusY = statusToDeal.media_attachments.get(0).meta.focus.y;
}
layoutMediaBinding.count.setVisibility(View.VISIBLE);
if (!fullAttachement && !singleImage) {
layoutMediaBinding.count.setText(String.format(Locale.getDefault(), "%d/%d", mediaPosition, statusToDeal.media_attachments.size()));
}
String finalUrl;
if (attachment.url == null) {
finalUrl = attachment.remote_url;
} else {
finalUrl = attachment.url;
}
layoutMediaBinding.media.setOnLongClickListener(v -> {
if (long_press_media) {
MediaHelper.manageMove(context, finalUrl, false);
}
return true;
});
if (attachment.type != null && (attachment.type.equalsIgnoreCase("video") || attachment.type.equalsIgnoreCase("gifv"))) {
layoutMediaBinding.playVideo.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.playVideo.setVisibility(View.GONE);
}
if (attachment.type != null && attachment.type.equalsIgnoreCase("audio")) {
layoutMediaBinding.playMusic.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.playMusic.setVisibility(View.GONE);
}
if (attachment.description != null && !attachment.description.isEmpty()) {
layoutMediaBinding.viewDescription.setVisibility(View.VISIBLE);
} else {
layoutMediaBinding.viewDescription.setVisibility(View.GONE);
}
if (!mediaObfuscated(statusToDeal) || expand_media) {
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_24);
RequestBuilder<Drawable> requestBuilder = Glide.with(layoutMediaBinding.media.getContext())
.load(attachment.preview_url);
if (!fullAttachement) {
requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY)));
} else {
requestBuilder = requestBuilder.placeholder(R.color.transparent_grey);
requestBuilder = requestBuilder.fitCenter();
}
requestBuilder.into(layoutMediaBinding.media);
} else {
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_off_24);
Glide.with(layoutMediaBinding.media.getContext())
.load(attachment.preview_url)
.apply(new RequestOptions().transform(new BlurTransformation(50, 3)))
// .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners((int) Helper.convertDpToPixel(3, context))))
.into(layoutMediaBinding.media);
}
if (statusToDeal.sensitive) {
Helper.changeDrawableColor(context, layoutMediaBinding.viewHide, ThemeHelper.getAttColor(context, R.attr.colorError));
} else {
Helper.changeDrawableColor(context, layoutMediaBinding.viewHide, R.color.white);
}
layoutMediaBinding.media.setOnClickListener(v -> {
if (statusToDeal.isMediaObfuscated && mediaObfuscated(statusToDeal) && !expand_media) {
statusToDeal.isMediaObfuscated = false;
int position = holder.getBindingAdapterPosition();
adapter.notifyItemChanged(position);
if (timeout > 0) {
new CountDownTimer((timeout * 1000L), 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
statusToDeal.isMediaObfuscated = true;
adapter.notifyItemChanged(position);
}
}.start();
}
return;
}
Intent mediaIntent = new Intent(context, MediaActivity.class);
Bundle b = new Bundle();
b.putInt(Helper.ARG_MEDIA_POSITION, mediaPosition);
b.putSerializable(Helper.ARG_MEDIA_ARRAY, new ArrayList<>(statusToDeal.media_attachments));
mediaIntent.putExtras(b);
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, layoutMediaBinding.media, statusToDeal.media_attachments.get(0).url);
// start the new activity
context.startActivity(mediaIntent, options.toBundle());
});
layoutMediaBinding.viewHide.setOnClickListener(v -> {
statusToDeal.sensitive = !statusToDeal.sensitive;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
if (fullAttachement || singleImage) {
layoutMediaBinding.getRoot().setPadding(0, 0, 0, 10);
} else {
layoutMediaBinding.getRoot().setPadding(0, 0, 10, 0);
}
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
mRecyclerView = recyclerView;
}
private static boolean mediaObfuscated(Status status) {
//Media is not sensitive and doesn't have a spoiler text
if (!status.isMediaObfuscated) {
@ -2146,6 +2159,90 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
return position;
}
public static void applyColor(Context context, StatusViewHolder holder) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
boolean customLight = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_LIGHT_COLORS), false);
boolean customDark = sharedpreferences.getBoolean(context.getString(R.string.SET_CUSTOMIZE_DARK_COLORS), false);
int theme_icons_color = -1;
int theme_statuses_color = -1;
int theme_boost_header_color = -1;
int theme_text_color = -1;
int theme_text_header_1_line = -1;
int theme_text_header_2_line = -1;
int link_color = -1;
if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { //LIGHT THEME
if (customLight) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_ICON), -1);
theme_statuses_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_BACKGROUND), -1);
theme_boost_header_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_BOOST_HEADER), -1);
theme_text_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_TEXT), -1);
theme_text_header_1_line = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_DISPLAY_NAME), -1);
theme_text_header_2_line = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_USERNAME), -1);
link_color = sharedpreferences.getInt(context.getString(R.string.SET_LIGHT_LINK), -1);
}
} else {
if (customDark) {
theme_icons_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_ICON), -1);
theme_statuses_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_BACKGROUND), -1);
theme_boost_header_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_BOOST_HEADER), -1);
theme_text_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_TEXT), -1);
theme_text_header_1_line = sharedpreferences.getInt(context.getString(R.string.SET_DARK_DISPLAY_NAME), -1);
theme_text_header_2_line = sharedpreferences.getInt(context.getString(R.string.SET_DARK_USERNAME), -1);
link_color = sharedpreferences.getInt(context.getString(R.string.SET_DARK_LINK), -1);
}
}
if (theme_icons_color != -1) {
Helper.changeDrawableColor(context, holder.binding.actionButtonReply, theme_icons_color);
Helper.changeDrawableColor(context, holder.binding.statusAddCustomEmoji, theme_icons_color);
Helper.changeDrawableColor(context, holder.binding.statusEmoji, theme_icons_color);
Helper.changeDrawableColor(context, holder.binding.actionButtonMore, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_round_star_24, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_round_repeat_24, theme_icons_color);
Helper.changeDrawableColor(context, holder.binding.visibility, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_round_star_border_24, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_person, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_bot, theme_icons_color);
Helper.changeDrawableColor(context, R.drawable.ic_round_reply_24, theme_icons_color);
holder.binding.actionButtonFavorite.setInActiveImageTintColor(theme_icons_color);
holder.binding.actionButtonBookmark.setInActiveImageTintColor(theme_icons_color);
holder.binding.actionButtonBoost.setInActiveImageTintColor(theme_icons_color);
holder.binding.replyCount.setTextColor(theme_icons_color);
}
if (theme_statuses_color != -1) {
holder.binding.cardviewContainer.setBackgroundColor(theme_statuses_color);
holder.binding.translationLabel.setBackgroundColor(theme_statuses_color);
}
if (theme_boost_header_color != -1) {
holder.binding.statusBoosterInfo.setBackgroundColor(theme_boost_header_color);
}
if (theme_text_color != -1) {
holder.binding.statusContent.setTextColor(theme_text_color);
holder.binding.statusContentTranslated.setTextColor(theme_text_color);
holder.binding.spoiler.setTextColor(theme_text_color);
holder.binding.dateShort.setTextColor(theme_text_color);
holder.binding.poll.pollInfo.setTextColor(theme_text_color);
holder.binding.cardDescription.setTextColor(theme_text_color);
holder.binding.time.setTextColor(theme_text_color);
holder.binding.reblogsCount.setTextColor(theme_text_color);
holder.binding.favoritesCount.setTextColor(theme_text_color);
holder.binding.favoritesCount.setTextColor(theme_text_color);
Helper.changeDrawableColor(context, holder.binding.repeatInfo, theme_text_color);
Helper.changeDrawableColor(context, holder.binding.favInfo, theme_text_color);
Helper.changeDrawableColor(context, R.drawable.ic_baseline_lock_24, theme_text_color);
}
if (theme_text_header_1_line != -1) {
holder.binding.displayName.setTextColor(theme_text_header_1_line);
}
if (theme_text_header_2_line != -1) {
holder.binding.username.setTextColor(theme_text_header_2_line);
}
if (link_color != -1) {
holder.binding.cardUrl.setTextColor(link_color);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
//Nothing to do with hidden statuses
@ -2155,12 +2252,22 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
Status status = statusList.get(position);
if (viewHolder.getItemViewType() == STATUS_VISIBLE) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class);
SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class);
statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, timelineType, minified, canBeFederated, checkRemotely, fetchMoreCallBack);
statusManagement(context, statusesVM, searchVM, holder, mRecyclerView, this, statusList, status, timelineType, minified, canBeFederated, checkRemotely, fetchMoreCallBack);
applyColor(context, holder);
} else if (viewHolder.getItemViewType() == STATUS_FILTERED_HIDE) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
if (status.isFetchMore && fetchMoreCallBack != null) {
holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE);
holder.bindingFilteredHide.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> {
@ -2191,10 +2298,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
} else {
holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE);
}
} else if (viewHolder.getItemViewType() == STATUS_FILTERED) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
holder.bindingFiltered.filteredText.setText(context.getString(R.string.filtered_by, status.filteredByApp.title));
holder.bindingFiltered.displayButton.setOnClickListener(v -> {
status.filteredByApp = null;
@ -2231,7 +2336,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
} else {
holder.bindingFiltered.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE);
}
} else if (viewHolder.getItemViewType() == STATUS_ART) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account);

View file

@ -17,12 +17,15 @@ package app.fedilab.android.ui.drawer;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import java.io.File;
@ -68,6 +71,12 @@ public class StatusDraftAdapter extends RecyclerView.Adapter<StatusDraftAdapter.
public void onBindViewHolder(@NonNull StatusDraftHolder holder, int position) {
StatusDraft statusDraft = statusDrafts.get(position);
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
//--- MAIN CONTENT ---
if (statusDraft.statusDraftList != null && statusDraft.statusDraftList.size() > 0) {
holder.binding.statusContent.setText(statusDraft.statusDraftList.get(0).text, TextView.BufferType.SPANNABLE);
@ -87,7 +96,7 @@ public class StatusDraftAdapter extends RecyclerView.Adapter<StatusDraftAdapter.
//--- DATE ---
holder.binding.date.setText(Helper.dateDiff(context, statusDraft.created_ad));
holder.binding.container.setOnClickListener(v -> {
holder.binding.cardviewContainer.setOnClickListener(v -> {
Intent intent = new Intent(context, ComposeActivity.class);
intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft);
context.startActivity(intent);

View file

@ -56,13 +56,13 @@ public class StatusHistoryAdapter extends RecyclerView.Adapter<RecyclerView.View
Status status = statuses.get(position);
holder.binding.statusContent.setText(
status.getSpanContent(context,
new WeakReference<>(holder.binding.statusContent)),
new WeakReference<>(holder.binding.statusContent), null),
TextView.BufferType.SPANNABLE);
if (status.spoiler_text != null && !status.spoiler_text.trim().isEmpty()) {
holder.binding.spoiler.setVisibility(View.VISIBLE);
holder.binding.spoiler.setText(
status.getSpanSpoiler(context,
new WeakReference<>(holder.binding.spoiler)),
new WeakReference<>(holder.binding.spoiler), null),
TextView.BufferType.SPANNABLE);
} else {
holder.binding.spoiler.setVisibility(View.GONE);

View file

@ -121,7 +121,7 @@ public class StatusScheduledAdapter extends RecyclerView.Adapter<StatusScheduled
holder.binding.statusContent.setText(statusContent);
}
holder.binding.container.setOnClickListener(v -> {
holder.binding.cardviewContainer.setOnClickListener(v -> {
if (statusDraft != null) {
Intent intent = new Intent(context, ComposeActivity.class);
intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft);

View file

@ -18,6 +18,7 @@ package app.fedilab.android.ui.drawer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -28,6 +29,7 @@ import androidx.annotation.NonNull;
import androidx.core.app.ActivityOptionsCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import java.lang.ref.WeakReference;
@ -76,7 +78,11 @@ public class SuggestionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
SuggestionViewHolder holder = (SuggestionViewHolder) viewHolder;
MastodonHelper.loadPPMastodon(holder.binding.avatar, account);
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(AccountsVM.class);
holder.binding.avatar.setOnClickListener(v -> {

View file

@ -16,11 +16,14 @@ package app.fedilab.android.ui.drawer;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import com.github.mikephil.charting.components.Description;
@ -52,6 +55,13 @@ public class TagAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static void tagManagement(Context context, TagViewHolder tagViewHolder, Tag tag) {
tagViewHolder.binding.tagName.setText(String.format("#%s", tag.name));
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
tagViewHolder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
tagViewHolder.binding.dividerCard.setVisibility(View.GONE);
}
List<Entry> trendsEntry = new ArrayList<>();
List<History> historyList = tag.history;

View file

@ -17,16 +17,20 @@ package app.fedilab.android.ui.drawer.admin;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import java.util.Locale;
import app.fedilab.android.R;
import app.fedilab.android.activities.admin.AdminAccountActivity;
import app.fedilab.android.client.entities.api.admin.AdminAccount;
import app.fedilab.android.databinding.DrawerAdminAccountBinding;
@ -63,8 +67,15 @@ public class AdminAccountAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
AdminAccount adminAccount = adminAccountList.get(position);
AccountAdminViewHolder holder = (AccountAdminViewHolder) viewHolder;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
holder.binding.dividerCard.setVisibility(View.GONE);
}
MastodonHelper.loadPPMastodon(holder.binding.pp, adminAccount.account);
holder.binding.adminAccountContainer.setOnClickListener(v -> {
holder.binding.cardviewContainer.setOnClickListener(v -> {
Intent intent = new Intent(context, AdminAccountActivity.class);
Bundle b = new Bundle();
b.putSerializable(Helper.ARG_ACCOUNT, adminAccount);

View file

@ -0,0 +1,57 @@
package app.fedilab.android.ui.fragment.settings;
/* Copyright 2022 Thomas Schneider
*
* This file is a part of Fedilab
*
* 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.
*
* Fedilab 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 Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;
import app.fedilab.android.R;
public class FragmentCustomDarkSettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_custom_dark);
createPref();
}
private void createPref() {
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
@Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
}

View file

@ -0,0 +1,57 @@
package app.fedilab.android.ui.fragment.settings;
/* Copyright 2022 Thomas Schneider
*
* This file is a part of Fedilab
*
* 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.
*
* Fedilab 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 Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;
import app.fedilab.android.R;
public class FragmentCustomLightSettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_custom_light);
createPref();
}
private void createPref() {
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
@Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
}

View file

@ -18,7 +18,11 @@ package app.fedilab.android.ui.fragment.settings;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.navigation.NavOptions;
import androidx.navigation.Navigation;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import app.fedilab.android.R;
@ -89,6 +93,61 @@ public class FragmentThemingSettings extends PreferenceFragmentCompat implements
if (SET_THEME_DEFAULT_DARK != null) {
SET_THEME_DEFAULT_DARK.getContext().setTheme(Helper.dialogStyle());
}
Preference SET_CUSTOMIZE_LIGHT_COLORS_ACTION = findPreference(getString(R.string.SET_CUSTOMIZE_LIGHT_COLORS_ACTION));
if (SET_CUSTOMIZE_LIGHT_COLORS_ACTION != null) {
SET_CUSTOMIZE_LIGHT_COLORS_ACTION.setOnPreferenceClickListener(preference -> {
NavOptions.Builder navBuilder = new NavOptions.Builder();
navBuilder.setEnterAnim(R.anim.enter).setExitAnim(R.anim.exit).setPopEnterAnim(R.anim.pop_enter).setPopExitAnim(R.anim.pop_exit);
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(R.id.FragmentCustomLightSettings, null, navBuilder.build());
return true;
});
}
Preference SET_CUSTOMIZE_DARK_COLORS_ACTION = findPreference(getString(R.string.SET_CUSTOMIZE_DARK_COLORS_ACTION));
if (SET_CUSTOMIZE_DARK_COLORS_ACTION != null) {
SET_CUSTOMIZE_DARK_COLORS_ACTION.setOnPreferenceClickListener(preference -> {
NavOptions.Builder navBuilder = new NavOptions.Builder();
navBuilder.setEnterAnim(R.anim.enter).setExitAnim(R.anim.exit).setPopEnterAnim(R.anim.pop_enter).setPopExitAnim(R.anim.pop_exit);
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(R.id.FragmentCustomDarkSettings, null, navBuilder.build());
return true;
});
}
Preference SET_RESET_CUSTOM_COLOR = findPreference(getString(R.string.SET_RESET_CUSTOM_COLOR));
if (SET_RESET_CUSTOM_COLOR != null) {
SET_RESET_CUSTOM_COLOR.getContext().setTheme(Helper.dialogStyle());
SET_RESET_CUSTOM_COLOR.setOnPreferenceClickListener(preference -> {
AlertDialog.Builder resetConfirm = new AlertDialog.Builder(requireActivity(), Helper.dialogStyle());
resetConfirm.setMessage(getString(R.string.reset_color));
resetConfirm.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss());
resetConfirm.setPositiveButton(R.string.reset, (dialog, which) -> {
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
if (sharedPreferences != null) {
sharedPreferences.edit().remove(getString(R.string.SET_LIGHT_BACKGROUND)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_LIGHT_BOOST_HEADER)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_LIGHT_DISPLAY_NAME)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_LIGHT_USERNAME)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_LIGHT_TEXT)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_LIGHT_LINK)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_LIGHT_ICON)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_DARK_BACKGROUND)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_DARK_BOOST_HEADER)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_DARK_DISPLAY_NAME)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_DARK_USERNAME)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_DARK_TEXT)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_DARK_LINK)).apply();
sharedPreferences.edit().remove(getString(R.string.SET_DARK_ICON)).apply();
}
dialog.dismiss();
});
resetConfirm.show();
return true;
});
}
}
}

View file

@ -140,7 +140,7 @@ public class FragmentMastodonConversation extends Fragment implements Conversati
timelineParams.fetchingMissing = fetchingMissing;
if (useCache) {
if (useCache && direction != FragmentMastodonTimeline.DIRECTION.SCROLL_TOP && direction != FragmentMastodonTimeline.DIRECTION.FETCH_NEW) {
getCachedConversations(direction, fetchingMissing, timelineParams);
} else {
getLiveConversations(direction, fetchingMissing, timelineParams, conversationToUpdate);
@ -150,7 +150,7 @@ public class FragmentMastodonConversation extends Fragment implements Conversati
private void getCachedConversations(FragmentMastodonTimeline.DIRECTION direction, boolean fetchingMissing, TimelinesVM.TimelineParams timelineParams) {
if (direction == null) {
timelinesVM.getConversations(conversationList, timelineParams)
timelinesVM.getConversationsCache(conversationList, timelineParams)
.observe(getViewLifecycleOwner(), conversationsCached -> {
if (conversationsCached == null || conversationsCached.conversations == null || conversationsCached.conversations.size() == 0) {
getLiveConversations(null, fetchingMissing, timelineParams, null);
@ -179,13 +179,18 @@ public class FragmentMastodonConversation extends Fragment implements Conversati
}
});
} else if (direction == FragmentMastodonTimeline.DIRECTION.REFRESH) {
timelinesVM.getConversations(conversationList, timelineParams)
timelinesVM.getConversationsCache(conversationList, timelineParams)
.observe(getViewLifecycleOwner(), notificationsRefresh -> {
if (conversationAdapter != null) {
dealWithPagination(notificationsRefresh, FragmentMastodonTimeline.DIRECTION.REFRESH, true, null);
if (notificationsRefresh == null || notificationsRefresh.conversations == null || notificationsRefresh.conversations.size() == 0) {
getLiveConversations(direction, fetchingMissing, timelineParams, null);
} else {
initializeConversationCommonView(notificationsRefresh);
if (conversationAdapter != null) {
dealWithPagination(notificationsRefresh, FragmentMastodonTimeline.DIRECTION.REFRESH, true, null);
} else {
initializeConversationCommonView(notificationsRefresh);
}
}
});
}
}

View file

@ -387,7 +387,7 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
}
timelineParams.excludeType = getExcludeType();
timelineParams.fetchingMissing = fetchingMissing;
if (useCache) {
if (useCache && direction != FragmentMastodonTimeline.DIRECTION.SCROLL_TOP && direction != FragmentMastodonTimeline.DIRECTION.FETCH_NEW) {
getCachedNotifications(direction, fetchingMissing, timelineParams);
} else {
getLiveNotifications(direction, fetchingMissing, timelineParams, notificationToUpdate);
@ -430,10 +430,14 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
} else if (direction == FragmentMastodonTimeline.DIRECTION.REFRESH) {
notificationsVM.getNotifications(notificationList, timelineParams)
.observe(getViewLifecycleOwner(), notificationsRefresh -> {
if (notificationAdapter != null) {
dealWithPagination(notificationsRefresh, FragmentMastodonTimeline.DIRECTION.REFRESH, true, null);
if (notificationsRefresh == null || notificationsRefresh.notifications == null || notificationsRefresh.notifications.size() == 0) {
getLiveNotifications(direction, fetchingMissing, timelineParams, null);
} else {
initializeNotificationView(notificationsRefresh);
if (notificationAdapter != null) {
dealWithPagination(notificationsRefresh, FragmentMastodonTimeline.DIRECTION.REFRESH, true, null);
} else {
initializeNotificationView(notificationsRefresh);
}
}
});
}

View file

@ -24,6 +24,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -64,8 +65,13 @@ public class NotificationsVM extends AndroidViewModel {
super(application);
}
private static void sortDesc(List<Notification> notificationList) {
Collections.sort(notificationList, (obj1, obj2) -> obj2.id.compareToIgnoreCase(obj1.id));
}
private static void addFetchMoreNotifications(List<Notification> notificationList, List<Notification> timelineNotifications, TimelinesVM.TimelineParams timelineParams) throws DBException {
if (notificationList != null && notificationList.size() > 0 && timelineNotifications != null && timelineNotifications.size() > 0) {
sortDesc(notificationList);
if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.REFRESH || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.SCROLL_TOP || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.FETCH_NEW) {
//When refreshing/scrolling to TOP, if last statuses fetched has a greater id from newest in cache, there is potential hole
if (notificationList.get(notificationList.size() - 1).id.compareToIgnoreCase(timelineNotifications.get(0).id) > 0) {

View file

@ -29,6 +29,7 @@ import androidx.lifecycle.MutableLiveData;
import androidx.preference.PreferenceManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -90,8 +91,18 @@ public class TimelinesVM extends AndroidViewModel {
super(application);
}
private static void sortDesc(List<Status> statusList) {
Collections.sort(statusList, (obj1, obj2) -> obj2.id.compareToIgnoreCase(obj1.id));
}
private static void sortDescConv(List<Conversation> conversationList) {
Collections.sort(conversationList, (obj1, obj2) -> obj2.id.compareToIgnoreCase(obj1.id));
}
private static void addFetchMore(List<Status> statusList, List<Status> timelineStatuses, TimelineParams timelineParams) throws DBException {
if (statusList != null && statusList.size() > 0 && timelineStatuses != null && timelineStatuses.size() > 0) {
sortDesc(statusList);
if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.REFRESH || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.SCROLL_TOP || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.FETCH_NEW) {
//When refreshing/scrolling to TOP, if last statuses fetched has a greater id from newest in cache, there is potential hole
if (statusList.get(statusList.size() - 1).id.compareToIgnoreCase(timelineStatuses.get(0).id) > 0) {
@ -114,6 +125,7 @@ public class TimelinesVM extends AndroidViewModel {
private static void addFetchMoreConversation(List<Conversation> conversationList, List<Conversation> timelineConversations, TimelineParams timelineParams) throws DBException {
if (conversationList != null && conversationList.size() > 0 && timelineConversations != null && timelineConversations.size() > 0) {
sortDescConv(conversationList);
if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.REFRESH || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.SCROLL_TOP || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.FETCH_NEW) {
//When refreshing/scrolling to TOP, if last statuses fetched has a greater id from newest in cache, there is potential hole
if (conversationList.get(conversationList.size() - 1).id.compareToIgnoreCase(timelineConversations.get(0).id) > 0) {

View file

@ -5,6 +5,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:fillColor="@android:color/white"
android:pathData="M17,3H7c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
</vector>

View file

@ -1,7 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path

View file

@ -5,6 +5,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="?attr/colorControlNormal"
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z" />
</vector>

View file

@ -1,11 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:autoMirrored="true"
android:tint="?attr/colorControlNormal"
android:viewportWidth="28"
android:viewportHeight="28">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M7,7h10v1.79c0,0.45 0.54,0.67 0.85,0.35l2.79,-2.79c0.2,-0.2 0.2,-0.51 0,-0.71l-2.79,-2.79c-0.31,-0.31 -0.85,-0.09 -0.85,0.36L17,5L6,5c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1L7,7zM17,17L7,17v-1.79c0,-0.45 -0.54,-0.67 -0.85,-0.35l-2.79,2.79c-0.2,0.2 -0.2,0.51 0,0.71l2.79,2.79c0.31,0.31 0.85,0.09 0.85,-0.36L7,19h11c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v3z" />
android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M17,3H7c-1.1,0 -2,0.9 -2,2v16l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M17,3L7,3c-1.1,0 -2,0.9 -2,2v16l7,-3 7,3L19,5c0,-1.1 -0.9,-2 -2,-2zM17,18l-5,-2.18L7,18L7,6c0,-0.55 0.45,-1 1,-1h8c0.55,0 1,0.45 1,1v12z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M7,7h10v1.79c0,0.45 0.54,0.67 0.85,0.35l2.79,-2.79c0.2,-0.2 0.2,-0.51 0,-0.71l-2.79,-2.79c-0.31,-0.31 -0.85,-0.09 -0.85,0.36L17,5L6,5c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1L7,7zM17,17L7,17v-1.79c0,-0.45 -0.54,-0.67 -0.85,-0.35l-2.79,2.79c-0.2,0.2 -0.2,0.51 0,0.71l2.79,2.79c0.31,0.31 0.85,0.09 0.85,-0.36L7,19h11c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v3z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="m9.559,8.159l0,-1.908c0,-1.068 -1.296,-1.608 -2.052,-0.852l-5.508,5.508c-0.468,0.468 -0.468,1.224 0,1.692l5.508,5.508c0.756,0.756 2.052,0.228 2.052,-0.84l0,-2.028c6,0 10.2,1.92 13.2,6.12 -1.2,-6 -4.8,-12 -13.2,-13.2z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M12,17.27l4.15,2.51c0.76,0.46 1.69,-0.22 1.49,-1.08l-1.1,-4.72l3.67,-3.18c0.67,-0.58 0.31,-1.68 -0.57,-1.75l-4.83,-0.41l-1.89,-4.46c-0.34,-0.81 -1.5,-0.81 -1.84,0L9.19,8.63L4.36,9.04c-0.88,0.07 -1.24,1.17 -0.57,1.75l3.67,3.18l-1.1,4.72c-0.2,0.86 0.73,1.54 1.49,1.08L12,17.27z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M19.65,9.04l-4.84,-0.42 -1.89,-4.45c-0.34,-0.81 -1.5,-0.81 -1.84,0L9.19,8.63l-4.83,0.41c-0.88,0.07 -1.24,1.17 -0.57,1.75l3.67,3.18 -1.1,4.72c-0.2,0.86 0.73,1.54 1.49,1.08l4.15,-2.5 4.15,2.51c0.76,0.46 1.69,-0.22 1.49,-1.08l-1.1,-4.73 3.67,-3.18c0.67,-0.58 0.32,-1.68 -0.56,-1.75zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z" />
</vector>

View file

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="28"
android:viewportHeight="28">
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z" />

View file

@ -14,16 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="6dp"
android:layout_marginTop="6dp">
android:layout_marginTop="6dp"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -154,4 +159,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,15 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginTop="12dp">
android:layout_marginHorizontal="6dp"
android:layout_marginTop="6dp"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -71,14 +77,14 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/list_action"
style="@style/Widget.AppCompat.Button.Colored"
style="@style/Widget.Material3.Button.Icon"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="12dp"
android:layout_marginTop="6dp"
android:insetTop="0dp"
android:insetBottom="0dp"
android:padding="6dp"
android:padding="0dp"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:icon="@drawable/ic_baseline_person_add_alt_1_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@ -86,4 +92,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -1,16 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/admin_account_container"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="6dp"
android:layout_marginTop="6dp">
android:layout_marginTop="6dp"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -140,5 +147,5 @@
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,19 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false">
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -96,4 +98,4 @@
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,17 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:id="@+id/cardview_container"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp">
android:layout_marginTop="6dp"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -115,4 +119,4 @@
tools:visibility="visible" />
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,13 +14,20 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
android:layout_marginHorizontal="6dp"
android:layout_marginTop="6dp"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -51,4 +58,4 @@
android:padding="6dp"
app:icon="@drawable/ic_baseline_delete_24" />
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,15 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/cardview_container"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin">
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -48,6 +54,7 @@
tools:text="User asked to follow you" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
@ -128,4 +135,4 @@
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,14 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
android:id="@+id/cardview_container"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -49,7 +56,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:textAppearance="@style/TextAppearance.Material3.HeadlineMedium"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/instance_pp"
app:layout_constraintTop_toTopOf="parent"
@ -99,4 +106,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardview_container"
@ -22,13 +22,10 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false"
android:clipChildren="false">
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
app:cardElevation="0dp"
app:strokeWidth="0dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/main_container"
@ -39,6 +36,16 @@
android:clipToPadding="false"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/fetch_more_container_top"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/status_booster_info"
@ -576,30 +583,30 @@
android:layout_height="48dp"
android:layout_marginStart="48dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="6dp"
android:clipChildren="false"
android:clipToPadding="false">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/action_button_reply_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="48dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
<androidx.appcompat.widget.AppCompatImageView
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/action_button_reply"
android:layout_width="28dp"
android:layout_height="28dp"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginStart="6dp"
android:adjustViewBounds="true"
android:clickable="true"
android:contentDescription="@string/reply"
android:focusable="true"
app:srcCompat="@drawable/ic_reply" />
app:srcCompat="@drawable/ic_round_reply_24" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/reply_count"
@ -607,6 +614,7 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="+"
tools:visibility="visible"
android:textColor="?colorControlNormal"
android:textSize="12sp"
android:visibility="gone"
@ -619,16 +627,14 @@
app:layout_constraintEnd_toStartOf="@+id/action_button_favorite"
app:layout_constraintStart_toEndOf="@+id/action_button_reply_container"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginStart="12dp"
android:layout_marginTop="2dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:adjustViewBounds="true"
android:contentDescription="@string/reblog_add"
app:sparkbutton_activeImage="@drawable/ic_repeat"
app:sparkbutton_activeImage="@drawable/ic_round_repeat_24"
app:sparkbutton_animationSpeed="1.5"
app:sparkbutton_iconSize="28dp"
app:sparkbutton_inActiveImage="@drawable/ic_repeat"
app:sparkbutton_iconSize="24dp"
app:sparkbutton_inActiveImage="@drawable/ic_round_repeat_24"
app:sparkbutton_primaryColor="@color/boost_icon"
app:sparkbutton_secondaryColor="@color/boost_icon" />
@ -638,17 +644,15 @@
app:layout_constraintEnd_toStartOf="@+id/action_button_bookmark"
app:layout_constraintStart_toEndOf="@+id/action_button_boost"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginTop="2dp"
android:adjustViewBounds="true"
android:contentDescription="@string/favourite_add"
app:sparkbutton_activeImage="@drawable/ic_baseline_star_24"
app:sparkbutton_activeImage="@drawable/ic_round_star_24"
app:sparkbutton_animationSpeed="1.5"
app:sparkbutton_iconSize="28dp"
app:sparkbutton_inActiveImage="@drawable/ic_star_outline"
app:sparkbutton_iconSize="24dp"
app:sparkbutton_inActiveImage="@drawable/ic_round_star_border_24"
app:sparkbutton_primaryColor="@color/marked_icon"
app:sparkbutton_secondaryColor="@color/marked_icon" />
@ -658,31 +662,29 @@
app:layout_constraintEnd_toStartOf="@+id/status_add_custom_emoji"
app:layout_constraintStart_toEndOf="@+id/action_button_favorite"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:adjustViewBounds="true"
android:contentDescription="@string/bookmark_add"
app:sparkbutton_activeImage="@drawable/ic_baseline_bookmark_24"
app:sparkbutton_activeImage="@drawable/ic_round_bookmark_24"
app:sparkbutton_animationSpeed="1.5"
app:sparkbutton_iconSize="24dp"
app:sparkbutton_inActiveImage="@drawable/ic_baseline_bookmark_border_24"
app:sparkbutton_inActiveImage="@drawable/ic_round_bookmark_border_24"
app:sparkbutton_primaryColor="@color/marked_icon"
app:sparkbutton_secondaryColor="@color/marked_icon" />
<androidx.appcompat.widget.AppCompatImageView
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/status_add_custom_emoji"
style="@style/Widget.Material3.Button.IconButton"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/status_emoji"
app:layout_constraintStart_toEndOf="@+id/action_button_bookmark"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/add_reaction"
android:padding="3dp"
android:src="@drawable/ic_baseline_emoji_emotions_24"
android:layout_gravity="center"
android:adjustViewBounds="true"
@ -691,17 +693,16 @@
android:visibility="gone"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatImageView
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/status_emoji"
style="@style/Widget.Material3.Button.IconButton"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/action_button_more"
app:layout_constraintStart_toEndOf="@+id/status_add_custom_emoji"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginStart="6dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/add_reaction"
android:padding="3dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:clickable="true"
@ -710,28 +711,28 @@
android:visibility="gone"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatImageView
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/action_button_more"
style="@style/Widget.Material3.Button.IconButton"
android:layout_gravity="center|end"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:contentDescription="@string/display_options"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintTop_toTopOf="parent"
android:clickable="true"
android:adjustViewBounds="true"
android:focusable="true"
app:srcCompat="@drawable/ic_more_horiz" />
app:srcCompat="@drawable/ic_round_more_horiz_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:id="@+id/layout_fetch_more"
layout="@layout/drawer_fetch_more"
android:visibility="gone"
tools:visibility="visible" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/fetch_more_container_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,15 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -106,4 +112,4 @@
</HorizontalScrollView>
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardview_container"
@ -23,9 +23,12 @@
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false">
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -78,4 +81,4 @@
tools:visibility="visible" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardview_container"
@ -23,9 +23,12 @@
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false">
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -47,4 +50,4 @@
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,17 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginTop="12dp"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false">
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -100,4 +104,4 @@
tools:text="@tools:sample/lorem/random" />
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,15 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -96,4 +102,4 @@
</HorizontalScrollView>
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,17 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginTop="12dp"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false">
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -98,4 +102,4 @@
tools:text="@tools:sample/lorem/random" />
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,15 +14,21 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="6dp"
android:layout_marginTop="6dp">
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -107,4 +113,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -14,12 +14,20 @@
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardview_container"
android:layout_marginHorizontal="@dimen/card_margin"
android:layout_marginTop="@dimen/card_margin"
android:clipChildren="false"
android:clipToPadding="false"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<View
android:id="@+id/divider_card"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorOutline" />
@ -64,4 +72,4 @@
android:layout_width="100dp"
android:layout_height="50dp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -12,8 +12,7 @@
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/media"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:layout_height="wrap_content"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.AppCompatImageView

View file

@ -105,6 +105,17 @@
android:name="app.fedilab.android.ui.fragment.settings.FragmentLanguageSettings"
android:label="@string/languages" />
<fragment
android:id="@+id/FragmentCustomLightSettings"
android:name="app.fedilab.android.ui.fragment.settings.FragmentCustomLightSettings"
android:label="@string/light_custom_colors" />
<fragment
android:id="@+id/FragmentCustomDarkSettings"
android:name="app.fedilab.android.ui.fragment.settings.FragmentCustomDarkSettings"
android:label="@string/cark_custom_colors" />
<activity
android:id="@+id/EditProfileActivity"
android:name="app.fedilab.android.activities.EditProfileActivity" />

View file

@ -735,4 +735,19 @@
<string name="set_dynamic_color">لون ديناميكي</string>
<string name="report_val1">لا يعجبني</string>
<string name="report_val_more1">ليس شيئاً تريد رؤيته</string>
<string name="set_notif_user_sign_up">تسجيل جديد (المشرفون)</string>
<string name="set_notif_admin_report">تقرير جديد (المشرفون)</string>
<string name="open_with_account">فتح باستخدام حساب آخر</string>
<string name="admin_reject_media">رفض ملفات الوسائط</string>
<string name="admin_reject_reports">رفض التقارير</string>
<string name="action_privacy_policy">سياسة الخصوصية</string>
<string name="domains">النطاقات</string>
<string name="keep_notifications">الاحتفاظ بالإشعارات</string>
<string name="reject_reports">رفض التقارير</string>
<string name="reject_media">رفض الوسائط</string>
<string name="severity">الشدة</string>
<string name="private_comment">تعليق خاص</string>
<string name="admin_reject_obfuscate">تشويش اسم النطاق</string>
<string name="type_default_theme_dark">المظهر الداكن الافتراضي</string>
<string name="public_comment">تعليق للعامة</string>
</resources>

View file

@ -497,7 +497,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -554,7 +554,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -540,7 +540,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -549,7 +549,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Επέλεξε μία κίνηση</string>
<string name="translation">Μετάφραση</string>
<string name="text_color_title">Χρώμα κειμένου</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Χρήση ενός προσαρμοσμένου θέματος</string>
<string name="theming">Θεματισμός</string>
<string name="data_export_theme">Έγινε εξαγωγή του θέματος</string>

View file

@ -530,7 +530,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -525,7 +525,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -524,7 +524,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -1,6 +1,10 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<attr name="linkColor" type="color" />
<style name="AppTheme" parent="Theme.Material3.Dark.NoActionBar">
<item name="linkColor">@color/md_theme_dark_primary</item>
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
@ -27,12 +31,10 @@
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
<item name="colorOnSurfaceInverse">@color/md_theme_dark_inverseOnSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_dark_inversePrimary</item>
<item name="android:navigationBarColor">?android:colorBackground</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">false</item>
<item name="android:isLightTheme" tools:targetApi="q">false</item>
<item name="windowNoTitle">true</item>
<!-- specify enter and exit transitions -->
<item name="android:windowEnterTransition">@android:transition/explode</item>
@ -45,6 +47,7 @@
</style>
<style name="AppThemeBar" parent="Theme.Material3.Dark">
<item name="linkColor">@color/md_theme_dark_primary</item>
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
@ -79,6 +82,7 @@
<style name="AppThemeAlertDialog" parent="Theme.Material3.Dark.Dialog.Alert">
<item name="linkColor">@color/md_theme_dark_primary</item>
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
@ -109,7 +113,10 @@
</style>
<!-- SOLARIZED DARK -->
<style name="SolarizedAppTheme" parent="AppTheme">
<item name="linkColor">@color/solarized_md_theme_dark_onPrimaryContainer</item>
<item name="colorPrimary">@color/solarized_md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/solarized_md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/solarized_md_theme_dark_primaryContainer</item>
@ -143,6 +150,7 @@
</style>
<style name="SolarizedAppThemeBar" parent="AppThemeBar">
<item name="linkColor">@color/solarized_md_theme_dark_onPrimaryContainer</item>
<item name="colorPrimary">@color/solarized_md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/solarized_md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/solarized_md_theme_dark_primaryContainer</item>
@ -175,7 +183,6 @@
<item name="colorPrimaryInverse">@color/solarized_md_theme_dark_inversePrimary</item>
</style>
<style name="TransparentSolarized" parent="SolarizedAppThemeBar">
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowContentOverlay">@null</item>
@ -185,6 +192,7 @@
</style>
<style name="SolarizedAlertDialog" parent="Theme.Material3.Dark.Dialog.Alert">
<item name="linkColor">@color/solarized_md_theme_dark_onPrimaryContainer</item>
<item name="colorPrimary">@color/solarized_md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/solarized_md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/solarized_md_theme_dark_primaryContainer</item>
@ -217,19 +225,22 @@
<item name="colorPrimaryInverse">@color/solarized_md_theme_dark_inversePrimary</item>
</style>
<!-- BLACK THEME -->
<style name="BlackAppTheme" parent="AppTheme">
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
<item name="linkColor">@color/black_200</item>
<item name="colorPrimary">@color/dracula_comment</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorPrimaryContainer">@color/black_400</item>
<item name="colorOnPrimaryContainer">@color/white</item>
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
<item name="colorSecondaryContainer">@color/black</item>
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
<item name="colorSecondary">@color/black_400</item>
<item name="colorOnSecondary">@color/white</item>
<item name="colorSecondaryContainer">@color/black_400</item>
<item name="colorOnSecondaryContainer">@color/white</item>
<item name="colorTertiary">@color/black_400</item>
<item name="colorOnTertiary">@color/white</item>
<item name="colorTertiaryContainer">@color/black_400</item>
<item name="colorOnTertiaryContainer">@color/white</item>
<item name="colorError">@color/solarized_md_theme_dark_error</item>
<item name="colorErrorContainer">@color/solarized_md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/solarized_md_theme_dark_onError</item>
@ -247,18 +258,19 @@
</style>
<style name="BlackAppThemeBar" parent="AppThemeBar">
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
<item name="linkColor">@color/black_200</item>
<item name="colorPrimary">@color/dracula_comment</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorPrimaryContainer">@color/black_400</item>
<item name="colorOnPrimaryContainer">@color/white</item>
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
<item name="colorSecondary">@color/black_400</item>
<item name="colorOnSecondary">@color/white</item>
<item name="colorSecondaryContainer">@color/black_400</item>
<item name="colorOnSecondaryContainer">@color/white</item>
<item name="colorTertiary">@color/black_400</item>
<item name="colorOnTertiary">@color/white</item>
<item name="colorTertiaryContainer">@color/black_400</item>
<item name="colorOnTertiaryContainer">@color/white</item>
<item name="colorError">@color/solarized_md_theme_dark_error</item>
<item name="colorErrorContainer">@color/solarized_md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/solarized_md_theme_dark_onError</item>
@ -275,7 +287,6 @@
<item name="colorPrimaryInverse">@color/black</item>
</style>
<style name="TransparentBlack" parent="BlackAppThemeBar">
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowContentOverlay">@null</item>
@ -285,18 +296,19 @@
</style>
<style name="BlackAlertDialog" parent="Theme.Material3.Dark.Dialog.Alert">
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
<item name="linkColor">@color/black_200</item>
<item name="colorPrimary">@color/dracula_comment</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorPrimaryContainer">@color/black_400</item>
<item name="colorOnPrimaryContainer">@color/white</item>
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
<item name="colorSecondary">@color/black_400</item>
<item name="colorOnSecondary">@color/white</item>
<item name="colorSecondaryContainer">@color/black_400</item>
<item name="colorOnSecondaryContainer">@color/white</item>
<item name="colorTertiary">@color/black_400</item>
<item name="colorOnTertiary">@color/white</item>
<item name="colorTertiaryContainer">@color/black_400</item>
<item name="colorOnTertiaryContainer">@color/white</item>
<item name="colorError">@color/solarized_md_theme_dark_error</item>
<item name="colorErrorContainer">@color/solarized_md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/solarized_md_theme_dark_onError</item>
@ -313,4 +325,106 @@
<item name="colorPrimaryInverse">@color/black</item>
</style>
<!-- DRACULA THEME -->
<style name="DraculaAppTheme" parent="AppTheme">
<item name="linkColor">@color/dracula_pink</item>
<item name="colorPrimary">@color/dracula_comment</item>
<item name="colorOnPrimary">@color/dracula_foreground</item>
<item name="colorPrimaryContainer">@color/dracula_green</item>
<item name="colorOnPrimaryContainer">@color/black</item>
<item name="colorSecondary">@color/dracula_orange</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorSecondaryContainer">@color/dracula_cyan</item>
<item name="colorOnSecondaryContainer">@color/black</item>
<item name="colorTertiary">@color/dracula_pink</item>
<item name="colorOnTertiary">@color/black</item>
<item name="colorTertiaryContainer">@color/dracula_orange</item>
<item name="colorOnTertiaryContainer">@color/black</item>
<item name="colorError">@color/solarized_md_theme_dark_error</item>
<item name="colorErrorContainer">@color/solarized_md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/solarized_md_theme_dark_onError</item>
<item name="colorOnErrorContainer">@color/solarized_md_theme_dark_onErrorContainer</item>
<item name="android:colorBackground">@color/dracula_background</item>
<item name="colorOnBackground">@color/dracula_foreground</item>
<item name="colorSurface">@color/dracula_background</item>
<item name="colorOnSurface">@color/dracula_foreground</item>
<item name="colorSurfaceVariant">@color/dracula_current_Line</item>
<item name="colorOnSurfaceVariant">@color/dracula_foreground</item>
<item name="colorOutline">@color/solarized_md_theme_dark_outline</item>
<item name="colorOnSurfaceInverse">@color/dracula_comment</item>
<item name="colorSurfaceInverse">@color/dracula_foreground</item>
<item name="colorPrimaryInverse">@color/dracula_comment</item>
</style>
<style name="DraculaAppThemeBar" parent="AppThemeBar">
<item name="linkColor">@color/dracula_pink</item>
<item name="colorPrimary">@color/dracula_comment</item>
<item name="colorOnPrimary">@color/dracula_foreground</item>
<item name="colorPrimaryContainer">@color/dracula_green</item>
<item name="colorOnPrimaryContainer">@color/black</item>
<item name="colorSecondary">@color/dracula_orange</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorSecondaryContainer">@color/dracula_cyan</item>
<item name="colorOnSecondaryContainer">@color/black</item>
<item name="colorTertiary">@color/dracula_pink</item>
<item name="colorOnTertiary">@color/black</item>
<item name="colorTertiaryContainer">@color/dracula_orange</item>
<item name="colorOnTertiaryContainer">@color/black</item>
<item name="colorError">@color/solarized_md_theme_dark_error</item>
<item name="colorErrorContainer">@color/solarized_md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/solarized_md_theme_dark_onError</item>
<item name="colorOnErrorContainer">@color/solarized_md_theme_dark_onErrorContainer</item>
<item name="android:colorBackground">@color/dracula_background</item>
<item name="colorOnBackground">@color/dracula_foreground</item>
<item name="colorSurface">@color/dracula_background</item>
<item name="colorOnSurface">@color/dracula_foreground</item>
<item name="colorSurfaceVariant">@color/dracula_current_Line</item>
<item name="colorOnSurfaceVariant">@color/dracula_foreground</item>
<item name="colorOutline">@color/solarized_md_theme_dark_outline</item>
<item name="colorOnSurfaceInverse">@color/dracula_comment</item>
<item name="colorSurfaceInverse">@color/dracula_foreground</item>
<item name="colorPrimaryInverse">@color/dracula_comment</item>
</style>
<style name="TransparentDracula" parent="DraculaAppThemeBar">
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="DraculaAlertDialog" parent="Theme.Material3.Dark.Dialog.Alert">
<item name="linkColor">@color/dracula_pink</item>
<item name="colorPrimary">@color/dracula_comment</item>
<item name="colorOnPrimary">@color/dracula_foreground</item>
<item name="colorPrimaryContainer">@color/dracula_green</item>
<item name="colorOnPrimaryContainer">@color/black</item>
<item name="colorSecondary">@color/dracula_orange</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorSecondaryContainer">@color/dracula_cyan</item>
<item name="colorOnSecondaryContainer">@color/black</item>
<item name="colorTertiary">@color/dracula_pink</item>
<item name="colorOnTertiary">@color/black</item>
<item name="colorTertiaryContainer">@color/dracula_orange</item>
<item name="colorOnTertiaryContainer">@color/black</item>
<item name="colorError">@color/solarized_md_theme_dark_error</item>
<item name="colorErrorContainer">@color/solarized_md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/solarized_md_theme_dark_onError</item>
<item name="colorOnErrorContainer">@color/solarized_md_theme_dark_onErrorContainer</item>
<item name="android:colorBackground">@color/dracula_background</item>
<item name="colorOnBackground">@color/dracula_foreground</item>
<item name="colorSurface">@color/dracula_background</item>
<item name="colorOnSurface">@color/dracula_foreground</item>
<item name="colorSurfaceVariant">@color/dracula_current_Line</item>
<item name="colorOnSurfaceVariant">@color/dracula_foreground</item>
<item name="colorOutline">@color/solarized_md_theme_dark_outline</item>
<item name="colorOnSurfaceInverse">@color/dracula_comment</item>
<item name="colorSurfaceInverse">@color/dracula_foreground</item>
<item name="colorPrimaryInverse">@color/dracula_comment</item>
</style>
</resources>

View file

@ -528,7 +528,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Oversettelse</string>
<string name="text_color_title">Tekstfarge</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Bruk en egendefinert drakt</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -546,7 +546,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Tłumaczenie</string>
<string name="text_color_title">Kolor tekstu</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Użyj niestandardowego motywu</string>
<string name="theming">Motyw</string>
<string name="data_export_theme">Motyw został wyeksportowany</string>

View file

@ -534,7 +534,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -534,7 +534,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -529,7 +529,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -539,7 +539,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -534,7 +534,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

View file

@ -540,7 +540,7 @@
<string name="make_an_action">Make an action</string>
<string name="translation">Translation</string>
<string name="text_color_title">Text color</string>
<string name="text_color">Change the text color in pots</string>
<string name="text_color">Change the text color in messages</string>
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>

Some files were not shown because too many files have changed in this diff Show more