Compare commits

..

20 Commits

Author SHA1 Message Date
sk
bdcebf1576 boop verisom 2023-07-23 22:03:25 +02:00
sk
239b6f8202 fix pill-less navigation bar with labels 2023-07-21 11:41:34 +02:00
Jacoco
8404c79148 Re-implement some Akkoma specific things + hide filter settings (#729)
* Replace missing blurhash with accent color

* Correct Akkoma max account fields

* Skip discover on Akkoma

* Akkoma poll limits

* Hide filter settings on Akkoma

* clear search fragment on back

---------

Co-authored-by: sk <sk22@mailbox.org>
2023-07-21 02:29:38 +02:00
sk
5b2d04e09d add navigation bar tab labels - with option to hide them 2023-07-21 01:45:08 +02:00
sk
6bd13f99d2 add a readme link to the sauna repo 2023-07-21 01:15:35 +02:00
sk
2e8e12c1c8 add font tracking to label_medium 2023-07-21 01:08:07 +02:00
sk
17929a6b2d upstream was right about the weird padding
see "Navigation bar target size and margins" in
https://m3.material.io/components/navigation-bar/specs
2023-07-21 00:37:05 +02:00
sk
9455eaf820 parse html in pronouns 2023-07-21 00:30:30 +02:00
sk
cc054487ba configurable pronoun display 2023-07-21 00:22:52 +02:00
sk
e2df320d00 fix edit history header lines 2023-07-21 00:03:11 +02:00
sk
d74313f996 remove code for below-header reply lines 2023-07-20 23:58:18 +02:00
sk
b3cab67049 fix null pointer when accessing draft content type
closes sk22#734
2023-07-20 23:43:46 +02:00
sk
996f0b22b9 use theme color for alt badge text 2023-07-20 23:39:11 +02:00
sk
67952ea98e fix bugged alt text badge state 2023-07-20 23:39:00 +02:00
sk
7a02ca435f make alt badge more transparent
closes sk22#735
2023-07-20 23:19:47 +02:00
sk
8d55f62da9 round inset notifications
closes sk22#665
2023-07-18 12:54:04 +02:00
sk
ee0048a406 fix wrong margins for media posts with cw / without text 2023-07-18 09:59:47 +02:00
sk
14dcc769f2 fix monochrome icon
closes sk22#719
2023-07-18 09:01:13 +02:00
sk
f2e6255eb3 remove flagship instance reference 2023-07-18 08:52:40 +02:00
sk
7d392e20fb fix trending hashtags not loading
closes sk22#724
2023-07-18 08:40:54 +02:00
36 changed files with 356 additions and 203 deletions

View File

@@ -54,9 +54,15 @@ You can create drafts, edit them, send them manually later or set a scheduled da
## Installation
### IzzyOnDroid
### Google Play Store
[apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk](https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk)
[https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk](https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk)
<a href="https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk"><img height="50" alt="Get it on Google Play" src="img/google-play-badge.png"></a>
### F-Droid via IzzyOnDroid
[https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk](https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk)
<a href="https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk"><img height="50" alt="Get it on IzzyOnDroid" src="img/izzy-badge.png"></a>
@@ -64,11 +70,11 @@ Note that you'll need to add Izzy's F-Droid repository to your F-Droid app first
[`https://apt.izzysoft.de/fdroid/repo`](https://apt.izzysoft.de/fdroid/repo)
### Google Play Store
### F-Droid via saunarepo
[play.google.com/store/apps/details?id=org.joinmastodon.android.sk](https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk)
[https://repo.the-sauna.icu](https://repo.the-sauna.icu/)
<a href="https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk"><img height="50" alt="Get it on Google Play" src="img/google-play-badge.png"></a>
<a href="https://repo.the-sauna.icu"><img height="28" alt="Get it on SaunaRepo" src="img/saunarepo-badge.svg"></a>
### F-Droid

1
img/saunarepo-badge.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="124.25" height="28" role="img" aria-label="SAUNAREPO"><title>SAUNAREPO</title><g shape-rendering="crispEdges"><rect width="124.25" height="28" fill="#fb8441"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="100"><image x="9" y="7" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHRpdGxlPkFuZHJvaWQ8L3RpdGxlPjxwYXRoIGQ9Ik0xNy41MjMgMTUuMzQxNGMtLjU1MTEgMC0uOTk5My0uNDQ4Ni0uOTk5My0uOTk5N3MuNDQ4My0uOTk5My45OTkzLS45OTkzYy41NTExIDAgLjk5OTMuNDQ4My45OTkzLjk5OTMuMDAwMS41NTExLS40NDgyLjk5OTctLjk5OTMuOTk5N20tMTEuMDQ2IDBjLS41NTExIDAtLjk5OTMtLjQ0ODYtLjk5OTMtLjk5OTdzLjQ0ODItLjk5OTMuOTk5My0uOTk5M2MuNTUxMSAwIC45OTkzLjQ0ODMuOTk5My45OTkzIDAgLjU1MTEtLjQ0ODMuOTk5Ny0uOTk5My45OTk3bTExLjQwNDUtNi4wMmwxLjk5NzMtMy40NTkyYS40MTYuNDE2IDAgMDAtLjE1MjEtLjU2NzYuNDE2LjQxNiAwIDAwLS41Njc2LjE1MjFsLTIuMDIyMyAzLjUwM0MxNS41OTAyIDguMjQzOSAxMy44NTMzIDcuODUwOCAxMiA3Ljg1MDhzLTMuNTkwMi4zOTMxLTUuMTM2NyAxLjA5ODlMNC44NDEgNS40NDY3YS40MTYxLjQxNjEgMCAwMC0uNTY3Ny0uMTUyMS40MTU3LjQxNTcgMCAwMC0uMTUyMS41Njc2bDEuOTk3MyAzLjQ1OTJDMi42ODg5IDExLjE4NjcuMzQzMiAxNC42NTg5IDAgMTguNzYxaDI0Yy0uMzQzNS00LjEwMjEtMi42ODkyLTcuNTc0My02LjExODUtOS40Mzk2Ii8+PC9zdmc+"/><text transform="scale(.1)" x="721.25" y="175" textLength="802.5" fill="#fff" font-weight="bold">SAUNAREPO</text></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -15,8 +15,8 @@ android {
applicationId "org.joinmastodon.android.sk"
minSdk 23
targetSdk 33
versionCode 96
versionName "2.0.1+fork.96"
versionCode 97
versionName "2.0.1+fork.97"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resourceConfigurations += ['ar-rSA', 'ar-rDZ', 'be-rBY', 'bn-rBD', 'bs-rBA', 'ca-rES', 'cs-rCZ', 'da-rDK', 'de-rDE', 'el-rGR', 'es-rES', 'eu-rES', 'fa-rIR', 'fi-rFI', 'fil-rPH', 'fr-rFR', 'ga-rIE', 'gd-rGB', 'gl-rES', 'hi-rIN', 'hr-rHR', 'hu-rHU', 'hy-rAM', 'ig-rNG', 'in-rID', 'is-rIS', 'it-rIT', 'iw-rIL', 'ja-rJP', 'kab', 'ko-rKR', 'my-rMM', 'nl-rNL', 'no-rNO', 'oc-rFR', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ro-rRO', 'ru-rRU', 'si-rLK', 'sl-rSI', 'sv-rSE', 'th-rTH', 'tr-rTR', 'uk-rUA', 'ur-rIN', 'vi-rVN', 'zh-rCN', 'zh-rTW']
}

View File

@@ -36,18 +36,6 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="https" android:host="mastodon.social" android:pathPrefix="/@"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="https" android:host="mastodon.online" android:pathPrefix="/@"/>
</intent-filter>
</activity>
<activity
android:name=".PanicResponderActivity"
@@ -57,7 +45,6 @@
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="info.guardianproject.panic.action.TRIGGER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

View File

@@ -57,6 +57,8 @@ public class GlobalUserPreferences{
public static AutoRevealMode autoRevealEqualSpoilers;
public static ColorPreference color;
public static boolean disableM3PillActiveIndicator;
public static boolean showNavigationLabels;
public static boolean displayPronounsInTimelines, displayPronounsInThreads, displayPronounsInUserListings;
private static SharedPreferences getPrefs(){
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
@@ -111,6 +113,10 @@ public class GlobalUserPreferences{
autoRevealEqualSpoilers=AutoRevealMode.valueOf(prefs.getString("autoRevealEqualSpoilers", AutoRevealMode.THREADS.name()));
forwardReportDefault=prefs.getBoolean("forwardReportDefault", true);
disableM3PillActiveIndicator=prefs.getBoolean("disableM3PillActiveIndicator", false);
showNavigationLabels=prefs.getBoolean("showNavigationLabels", true);
displayPronounsInTimelines=prefs.getBoolean("displayPronounsInTimelines", true);
displayPronounsInThreads=prefs.getBoolean("displayPronounsInThreads", true);
displayPronounsInUserListings=prefs.getBoolean("displayPronounsInUserListings", true);
if (prefs.contains("prefixRepliesWithRe")) {
prefixReplies = prefs.getBoolean("prefixRepliesWithRe", false)
@@ -164,6 +170,10 @@ public class GlobalUserPreferences{
.putString("autoRevealEqualSpoilers", autoRevealEqualSpoilers.name())
.putBoolean("forwardReportDefault", forwardReportDefault)
.putBoolean("disableM3PillActiveIndicator", disableM3PillActiveIndicator)
.putBoolean("showNavigationLabels", showNavigationLabels)
.putBoolean("displayPronounsInTimelines", displayPronounsInTimelines)
.putBoolean("displayPronounsInThreads", displayPronounsInThreads)
.putBoolean("displayPronounsInUserListings", displayPronounsInUserListings)
.apply();
}

View File

@@ -449,7 +449,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
} else if (getArguments().containsKey("sourceContentType")) {
try {
String val = getArguments().getString("sourceContentType");
contentType = val == null ? null : ContentType.valueOf(val);
if (val != null) contentType = ContentType.valueOf(val);
} catch (IllegalArgumentException ignored) {}
}
@@ -1435,8 +1435,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
}
private void updateHeaders() {
UiUtils.setExtraTextInfo(getContext(), selfExtraText, null, false, localOnly || statusVisibility==StatusPrivacy.LOCAL, null);
if (replyTo != null) UiUtils.setExtraTextInfo(getContext(), extraText, pronouns, false, replyTo.localOnly || replyTo.visibility==StatusPrivacy.LOCAL, replyTo.account);
UiUtils.setExtraTextInfo(getContext(), selfExtraText, null, false, false, localOnly || statusVisibility==StatusPrivacy.LOCAL, null);
if (replyTo != null) UiUtils.setExtraTextInfo(getContext(), extraText, pronouns, true, false, replyTo.localOnly || replyTo.visibility==StatusPrivacy.LOCAL, replyTo.account);
}
private void buildVisibilityPopup(View v){

View File

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
import android.app.Fragment;
import android.app.NotificationManager;
import android.app.assist.AssistContent;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
@@ -126,12 +127,31 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
tabBarWrap=content.findViewById(R.id.tabbar_wrap);
// this one's for the pill haters (https://m3.material.io/components/navigation-bar/overview)
if (GlobalUserPreferences.disableM3PillActiveIndicator) {
for(int i=0; i<tabBar.getChildCount(); i++){
ViewGroup f=(ViewGroup) tabBar.getChildAt(i);
f.setBackgroundResource(R.drawable.bg_tabbar_tab_ripple);
if(GlobalUserPreferences.disableM3PillActiveIndicator){
tabBar.findViewById(R.id.tab_home_pill).setBackground(null);
tabBar.findViewById(R.id.tab_search_pill).setBackground(null);
tabBar.findViewById(R.id.tab_notifications_pill).setBackground(null);
tabBar.findViewById(R.id.tab_profile_pill).setBackgroundResource(R.drawable.bg_tab_profile);
View[] tabs={
tabBar.findViewById(R.id.tab_home),
tabBar.findViewById(R.id.tab_search),
tabBar.findViewById(R.id.tab_notifications),
tabBar.findViewById(R.id.tab_profile)
};
for(View tab : tabs){
tab.setBackgroundResource(R.drawable.bg_tabbar_tab_ripple);
((RippleDrawable) tab.getBackground())
.setRadius(V.dp(GlobalUserPreferences.showNavigationLabels ? 56 : 42));
}
tabBar.findViewById(R.id.tab_profile).setBackgroundResource(R.drawable.bg_tab_profile);
}
if(!GlobalUserPreferences.showNavigationLabels){
tabBar.findViewById(R.id.tab_home_label).setVisibility(View.GONE);
tabBar.findViewById(R.id.tab_search_label).setVisibility(View.GONE);
tabBar.findViewById(R.id.tab_notifications_label).setVisibility(View.GONE);
tabBar.findViewById(R.id.tab_profile_label).setVisibility(View.GONE);
}
tabBarAvatar=tabBar.findViewById(R.id.tab_profile_ava);

View File

@@ -1,7 +1,5 @@
package org.joinmastodon.android.fragments;
import static org.joinmastodon.android.fragments.ProfileAboutFragment.MAX_FIELDS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -175,6 +173,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private MenuItem editSaveMenuItem;
private boolean savingEdits;
private int maxFields = ProfileAboutFragment.MAX_FIELDS;
// from ProfileAboutFragment
public UsableRecyclerView list;
private AboutAdapter adapter;
@@ -200,6 +200,9 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
loaded=true;
if(!isOwnProfile)
loadRelationship();
else if (isInstanceAkkoma()) {
maxFields = getInstance().get().pleroma.metadata.fieldsLimits.maxFields;
}
}else{
profileAccountID=getArguments().getString("profileAccountID");
if(!getArguments().getBoolean("noAutoLoad", false))
@@ -1385,7 +1388,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
public int getItemCount(){
if(isInEditMode){
int size=fields.size();
if(size<MAX_FIELDS)
if(size<maxFields)
size++;
return size;
}
@@ -1510,7 +1513,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
@Override
public void onClick(){
fields.add(new AccountField());
if(fields.size()==MAX_FIELDS){ // replace this row with new row
if(fields.size()==maxFields){ // replace this row with new row
adapter.notifyItemChanged(fields.size()-1);
}else{
adapter.notifyItemInserted(fields.size()-1);

View File

@@ -143,7 +143,9 @@ public class StatusEditHistoryFragment extends StatusListFragment{
}
}
String sep = getString(R.string.sk_separator);
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" "+sep+" "+date, Collections.emptyList(), 0, null, null));
ReblogOrReplyLineStatusDisplayItem line=new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" "+sep+" "+date, Collections.emptyList(), 0, null, null);
line.needBottomPadding=true;
items.add(0, line);
}
return items;
}

View File

@@ -54,6 +54,8 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
private String accountID;
private String currentQuery;
private boolean disableDiscover;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
@@ -155,6 +157,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
}
});
disableDiscover=getArguments().getBoolean("disableDiscover");
searchView=view.findViewById(R.id.search_fragment);
if(searchFragment==null){
searchFragment=new SearchFragment();
@@ -170,8 +173,9 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
searchBack.setOnClickListener(v->{
if(searchActive) exitSearch(); else openSearch();
});
if(searchActive){
searchBack.setImageResource(R.drawable.ic_fluent_arrow_left_24_regular);
if(searchActive) searchBack.setImageResource(R.drawable.ic_fluent_arrow_left_24_regular);
else searchBack.setEnabled(false);
if(searchActive || disableDiscover){
pager.setVisibility(View.GONE);
tabLayout.setVisibility(View.GONE);
searchView.setVisibility(View.VISIBLE);
@@ -211,8 +215,8 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
}
public void loadData(){
if(postsFragment!=null && !postsFragment.loaded && !postsFragment.dataLoading)
postsFragment.loadData();
if(hashtagsFragment!=null && !hashtagsFragment.loaded && !hashtagsFragment.dataLoading)
hashtagsFragment.loadData();
}
private void enterSearch(){
@@ -232,15 +236,18 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
if(!searchActive)
return;
searchActive=false;
pager.setVisibility(View.VISIBLE);
tabLayout.setVisibility(View.VISIBLE);
searchView.setVisibility(View.GONE);
searchText.setText(R.string.sk_search_fediverse);
searchBack.setImageResource(R.drawable.ic_fluent_search_24_regular);
searchBack.setEnabled(false);
searchBack.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
tabsDivider.setVisibility(View.VISIBLE);
currentQuery=null;
searchFragment.clear();
if(disableDiscover) return;
pager.setVisibility(View.VISIBLE);
tabLayout.setVisibility(View.VISIBLE);
searchView.setVisibility(View.GONE);
tabsDivider.setVisibility(View.VISIBLE);
}
private Fragment getFragmentForPage(int page){

View File

@@ -54,7 +54,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
setRetainInstance(true);
setEmptyText(R.string.no_search_results);
setEmptyText(R.string.sk_recent_searches_placeholder);
loadData();
}
@@ -173,13 +173,16 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
}
public void setQuery(String q, SearchResult.Type filter){
if(q.isBlank())
if(q.isBlank()) {
setEmptyText(R.string.sk_recent_searches_placeholder);
return;
}
if(currentRequest!=null){
currentRequest.cancel();
currentRequest=null;
}
currentQuery=q;
setEmptyText(R.string.no_search_results);
if(filter==null)
currentFilter=EnumSet.allOf(SearchResult.Type.class);
else
@@ -221,6 +224,13 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
}
}
public void clear() {
data.clear();
preloadedData.clear();
adapter.notifyDataSetChanged();
V.setVisibilityAnimated(content, View.GONE);
}
@Override
public Uri getWebUri(Uri.Builder base) {
Uri.Builder searchUri = base.path("/search");

View File

@@ -37,8 +37,9 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
private CheckableListItem<Void> revealCWsItem, hideSensitiveMediaItem, interactionCountsItem, emojiInNamesItem;
// MEGALODON
private CheckableListItem<Void> trueBlackModeItem, marqueeItem, disableSwipeItem, reduceMotionItem, altIndicatorItem, noAltIndicatorItem, collapsePostsItem, spectatorModeItem, hideFabItem, translateOpenedItem, disablePillItem;
private CheckableListItem<Void> trueBlackModeItem, marqueeItem, disableSwipeItem, reduceMotionItem, altIndicatorItem, noAltIndicatorItem, collapsePostsItem, spectatorModeItem, hideFabItem, translateOpenedItem, disablePillItem, showNavigationLabelsItem;
private ListItem<Void> colorItem, publishTextItem, autoRevealCWsItem;
private CheckableListItem<Void> pronounsInUserListingsItem, pronounsInTimelinesItem, pronounsInThreadsItem;
private AccountLocalPreferences lp;
@@ -67,7 +68,11 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
spectatorModeItem=new CheckableListItem<>(R.string.sk_settings_hide_interaction, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.spectatorMode, R.drawable.ic_fluent_star_off_24_regular, ()->toggleCheckableItem(spectatorModeItem)),
hideFabItem=new CheckableListItem<>(R.string.sk_settings_hide_fab, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.autoHideFab, R.drawable.ic_fluent_edit_24_regular, ()->toggleCheckableItem(hideFabItem)),
translateOpenedItem=new CheckableListItem<>(R.string.sk_settings_translate_only_opened, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.translateButtonOpenedOnly, R.drawable.ic_fluent_translate_24_regular, ()->toggleCheckableItem(translateOpenedItem)),
disablePillItem=new CheckableListItem<>(R.string.sk_disable_pill_shaped_active_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableM3PillActiveIndicator, R.drawable.ic_fluent_pill_24_regular, ()->toggleCheckableItem(disablePillItem))
disablePillItem=new CheckableListItem<>(R.string.sk_disable_pill_shaped_active_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableM3PillActiveIndicator, R.drawable.ic_fluent_pill_24_regular, ()->toggleCheckableItem(disablePillItem)),
showNavigationLabelsItem=new CheckableListItem<>(R.string.sk_settings_show_labels_in_navigation_bar, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNavigationLabels, R.drawable.ic_fluent_tag_24_regular, ()->toggleCheckableItem(showNavigationLabelsItem), true),
pronounsInTimelinesItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_timelines, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInTimelines, 0, ()->toggleCheckableItem(pronounsInTimelinesItem)),
pronounsInThreadsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_threads, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInThreads, 0, ()->toggleCheckableItem(pronounsInThreadsItem)),
pronounsInUserListingsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_user_listings, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInUserListings, 0, ()->toggleCheckableItem(pronounsInUserListingsItem))
));
trueBlackModeItem.checkedChangeListener=checked->onTrueBlackModeClick();
}
@@ -90,7 +95,8 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
super.onHidden();
boolean restartPlease=
GlobalUserPreferences.disableM3PillActiveIndicator!=disablePillItem.checked;
GlobalUserPreferences.disableM3PillActiveIndicator!=disablePillItem.checked ||
GlobalUserPreferences.showNavigationLabels!=showNavigationLabelsItem.checked;
lp.revealCWs=revealCWsItem.checked;
lp.hideSensitiveMedia=hideSensitiveMediaItem.checked;
@@ -107,6 +113,10 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
GlobalUserPreferences.autoHideFab=hideFabItem.checked;
GlobalUserPreferences.translateButtonOpenedOnly=translateOpenedItem.checked;
GlobalUserPreferences.disableM3PillActiveIndicator=disablePillItem.checked;
GlobalUserPreferences.showNavigationLabels=showNavigationLabelsItem.checked;
GlobalUserPreferences.displayPronounsInTimelines=pronounsInTimelinesItem.checked;
GlobalUserPreferences.displayPronounsInThreads=pronounsInThreadsItem.checked;
GlobalUserPreferences.displayPronounsInUserListings=pronounsInUserListingsItem.checked;
GlobalUserPreferences.save();
if(restartPlease) restartActivityToApplyNewTheme();
else E.post(new StatusDisplaySettingsChangedEvent(accountID));

View File

@@ -16,6 +16,7 @@ import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.viewmodel.ListItem;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
@@ -29,6 +30,7 @@ import me.grishka.appkit.Nav;
import me.grishka.appkit.utils.MergeRecyclerAdapter;
public class SettingsMainFragment extends BaseSettingsFragment<Void>{
private AccountSession account;
private boolean loggedOut;
private HideableSingleViewRecyclerAdapter bannerAdapter;
private Button updateButton1, updateButton2;
@@ -47,23 +49,27 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
account = AccountSessionManager.get(accountID);
setTitle(R.string.settings);
setSubtitle(AccountSessionManager.get(accountID).getFullUsername());
setSubtitle(account.getFullUsername());
onDataLoaded(List.of(
new ListItem<>(R.string.settings_behavior, 0, R.drawable.ic_fluent_settings_24_regular, this::onBehaviorClick),
new ListItem<>(R.string.settings_display, 0, R.drawable.ic_fluent_color_24_regular, this::onDisplayClick),
new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick),
new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_fluent_alert_24_regular, this::onNotificationsClick),
new ListItem<>(R.string.sk_settings_instance, 0, R.drawable.ic_fluent_server_24_regular, this::onInstanceClick),
new ListItem<>(getString(R.string.about_app, getString(R.string.sk_app_name)), null, R.drawable.ic_fluent_info_24_regular, this::onAboutClick, null, 0, true),
new ListItem<>(R.string.log_out, 0, R.drawable.ic_fluent_sign_out_24_regular, this::onLogOutClick, R.attr.colorM3Error, false)
));
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(account.domain);
if (!instance.isAkkoma())
data.add(2, new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick));
if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){
data.add(0, new ListItem<>("Debug settings", null, R.drawable.ic_fluent_wrench_screwdriver_24_regular, ()->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
}
AccountSessionManager.get(accountID).reloadPreferences(null);
account.reloadPreferences(null);
E.register(this);
}
@@ -80,7 +86,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
protected void onHidden(){
super.onHidden();
if(!loggedOut)
AccountSessionManager.get(accountID).savePreferencesIfPending();
account.savePreferencesIfPending();
}
@Override
@@ -147,7 +153,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
new M3AlertDialogBuilder(getActivity())
.setMessage(getString(R.string.confirm_log_out, session.getFullUsername()))
.setPositiveButton(R.string.log_out, (dialog, which)->AccountSessionManager.get(accountID).logOut(getActivity(), ()->{
.setPositiveButton(R.string.log_out, (dialog, which)->account.logOut(getActivity(), ()->{
loggedOut=true;
getActivity().finish();
Intent intent=new Intent(getActivity(), MainActivity.class);

View File

@@ -3,16 +3,15 @@ package org.joinmastodon.android.ui.displayitems;
import android.content.Context;
import android.view.ViewGroup;
import android.widget.Space;
import android.widget.TextView;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import me.grishka.appkit.utils.V;
public class InsetDummyStatusDisplayItem extends StatusDisplayItem {
public class DummyStatusDisplayItem extends StatusDisplayItem {
private final boolean addMediaGridMargin;
public InsetDummyStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, boolean addMediaGridMargin) {
public DummyStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, boolean addMediaGridMargin) {
super(parentID, parentFragment);
this.addMediaGridMargin = addMediaGridMargin;
}
@@ -22,19 +21,19 @@ public class InsetDummyStatusDisplayItem extends StatusDisplayItem {
return Type.DUMMY;
}
public static class Holder extends StatusDisplayItem.Holder<InsetDummyStatusDisplayItem> {
public static class Holder extends StatusDisplayItem.Holder<DummyStatusDisplayItem> {
public Holder(Context context) {
super(new Space(context));
}
@Override
public void onBind(InsetDummyStatusDisplayItem item) {
public void onBind(DummyStatusDisplayItem item) {
// BetterItemAnimator appears not to handle InsetStatusItemDecoration's getItemOffsets
// correctly, causing removed inset views to jump while animating. i don't quite
// understand it, but this workaround appears to work.
// see InsetStatusItemDecoration#getItemOffsets
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
params.setMargins(0, item.addMediaGridMargin ? V.dp(4) : 0, 0, V.dp(16));
params.setMargins(0, item.addMediaGridMargin ? V.dp(0) : 0, 0, V.dp(16));
itemView.setLayoutParams(params);
}
}

View File

@@ -337,7 +337,8 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0);
if(TextUtils.isEmpty(item.extraText)){
if (item.status != null) {
UiUtils.setExtraTextInfo(item.parentFragment.getContext(), extraText, pronouns, item.status.visibility==StatusPrivacy.DIRECT, item.status.localOnly || item.status.visibility==StatusPrivacy.LOCAL, item.status.account);
boolean displayPronouns=item.parentFragment instanceof ThreadFragment ? GlobalUserPreferences.displayPronounsInThreads : GlobalUserPreferences.displayPronounsInTimelines;
UiUtils.setExtraTextInfo(item.parentFragment.getContext(), extraText, pronouns, displayPronouns, item.status.visibility==StatusPrivacy.DIRECT, item.status.localOnly || item.status.visibility==StatusPrivacy.LOCAL, item.status.account);
}
}else{
extraText.setVisibility(View.VISIBLE);

View File

@@ -242,6 +242,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
if(altTextAnimator!=null)
altTextAnimator.cancel();
// V.setVisibilityAnimated(hideSensitiveButton, View.GONE);
V.cancelVisibilityAnimation(altTextWrapper);
v.setVisibility(View.INVISIBLE);
int index=(Integer)v.getTag();
altTextIndex=index;
@@ -254,7 +255,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
noAltText.setVisibility(!hasAltText && showNoAltIndicator ? View.VISIBLE : View.GONE);
altText.setText(att.description);
altTextWrapper.setVisibility(View.VISIBLE);
altTextWrapper.setBackgroundResource(hasAltText ? R.drawable.bg_image_alt_overlay : R.drawable.bg_image_no_alt_overlay);
altTextWrapper.setBackgroundResource(hasAltText ? R.drawable.bg_image_alt_text_overlay : R.drawable.bg_image_no_alt_overlay);
altTextWrapper.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
@Override
public boolean onPreDraw(){
@@ -317,6 +318,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
altTextAnimator.cancel();
// V.setVisibilityAnimated(hideSensitiveButton, item.status.sensitive ? View.VISIBLE : View.GONE);
V.cancelVisibilityAnimation(altTextWrapper);
View btn=controllers.get(altTextIndex).btnsWrap;
int i=0;
for(MediaAttachmentViewController c:controllers){
@@ -365,8 +367,8 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
@Override
public void onAnimationEnd(Animator animation){
altTextAnimator=null;
altTextWrapper.setVisibility(View.GONE);
btn.setVisibility(View.VISIBLE);
V.setVisibilityAnimated(altTextWrapper, View.GONE);
V.setVisibilityAnimated(btn, View.VISIBLE);
btn.setAlpha(1);
}
});

View File

@@ -40,7 +40,7 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
private int iconEnd;
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper(), fullTextEmojiHelper;
private View.OnClickListener handleClick;
boolean belowHeader, needBottomPadding;
public boolean needBottomPadding;
ReblogOrReplyLineStatusDisplayItem extra;
CharSequence fullText;
@@ -131,7 +131,6 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
if (visibilityText != 0) text.setContentDescription(item.text + " (" + ctx.getString(visibilityText) + ")");
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
text.setTextAppearance(item.belowHeader ? R.style.m3_label_large : R.style.m3_title_small);
text.setCompoundDrawableTintList(text.getTextColors());
}
@@ -141,10 +140,6 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
if (item.extra != null) bindLine(item.extra, extraText);
extraText.setVisibility(item.extra == null ? View.GONE : View.VISIBLE);
separator.setVisibility(item.extra == null ? View.GONE : View.VISIBLE);
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.bottomMargin = item.belowHeader ? V.dp(-6) : V.dp(-12);
params.topMargin = item.belowHeader ? V.dp(-6) : 0;
itemView.setLayoutParams(params);
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0);
layoutLine();
}

View File

@@ -3,6 +3,7 @@ package org.joinmastodon.android.ui.displayitems;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@@ -25,12 +26,12 @@ import org.joinmastodon.android.model.LegacyFilter;
import org.joinmastodon.android.model.FilterAction;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.FilterResult;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.Poll;
import org.joinmastodon.android.model.ScheduledStatus;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.viewholders.AccountViewHolder;
import org.joinmastodon.android.utils.StatusFilterPredicate;
import org.parceler.Parcels;
@@ -113,7 +114,7 @@ public abstract class StatusDisplayItem{
case SPOILER, FILTER_SPOILER -> new SpoilerStatusDisplayItem.Holder(activity, parent, type);
case SECTION_HEADER -> null; // new SectionHeaderStatusDisplayItem.Holder(activity, parent);
case NOTIFICATION_HEADER -> new NotificationHeaderStatusDisplayItem.Holder(activity, parent);
case DUMMY -> new InsetDummyStatusDisplayItem.Holder(activity);
case DUMMY -> new DummyStatusDisplayItem.Holder(activity);
};
}
@@ -240,17 +241,26 @@ public abstract class StatusDisplayItem{
}
}
boolean hasSpoiler=!TextUtils.isEmpty(statusForContent.spoilerText);
if(!TextUtils.isEmpty(statusForContent.content)){
SpannableStringBuilder parsedText=HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID);
HtmlParser.applyFilterHighlights(fragment.getActivity(), parsedText, status.filtered);
TextStatusDisplayItem text=new TextStatusDisplayItem(parentID, HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID), fragment, statusForContent, (flags & FLAG_NO_TRANSLATE) != 0);
contentItems.add(text);
} else if (header!=null){
}else if(!hasSpoiler && header!=null){
header.needBottomPadding=true;
}else if(hasSpoiler){
contentItems.add(new DummyStatusDisplayItem(parentID, fragment, true));
}
List<Attachment> imageAttachments=statusForContent.mediaAttachments.stream().filter(att->att.type.isImage()).collect(Collectors.toList());
if(!imageAttachments.isEmpty()){
int color = UiUtils.getThemeColor(fragment.getContext(), R.attr.colorM3SurfaceVariant);
for (Attachment att : imageAttachments) {
if (att.blurhashPlaceholder == null) {
att.blurhashPlaceholder = new ColorDrawable(color);
}
}
PhotoLayoutHelper.TiledLayoutResult layout=PhotoLayoutHelper.processThumbs(imageAttachments);
MediaGridStatusDisplayItem mediaGrid=new MediaGridStatusDisplayItem(parentID, fragment, layout, imageAttachments, statusForContent);
if((flags & FLAG_MEDIA_FORCE_HIDDEN)!=0)
@@ -287,7 +297,7 @@ public abstract class StatusDisplayItem{
boolean inset=(flags & FLAG_INSET)!=0;
// add inset dummy so last content item doesn't clip out of inset bounds
if (inset) {
items.add(new InsetDummyStatusDisplayItem(parentID, fragment,
items.add(new DummyStatusDisplayItem(parentID, fragment,
!contentItems.isEmpty() && contentItems
.get(contentItems.size() - 1) instanceof MediaGridStatusDisplayItem));
}

View File

@@ -27,7 +27,7 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
public InsetStatusItemDecoration(BaseStatusListFragment<?> listFragment){
this.listFragment=listFragment;
bgColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3SurfaceVariant);
bgColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3Surface);
borderColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3OutlineVariant);
}
@@ -65,13 +65,13 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
paint.setColor(bgColor);
rect.left=V.dp(12);
rect.right=list.getWidth()-V.dp(12);
rect.inset(V.dp(4), V.dp(4));
c.drawRoundRect(rect, V.dp(4), V.dp(4), paint);
rect.inset(V.dp(4), V.dp(0));
c.drawRoundRect(rect, V.dp(12), V.dp(12), paint);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(V.dp(1));
paint.setColor(borderColor);
rect.inset(paint.getStrokeWidth()/2f, paint.getStrokeWidth()/2f);
c.drawRoundRect(rect, V.dp(4), V.dp(4), paint);
c.drawRoundRect(rect, V.dp(12), V.dp(12), paint);
}
@Override
@@ -85,10 +85,10 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
boolean topSiblingInset=pos>0 && displayItems.get(pos-1).inset;
boolean bottomSiblingInset=pos<displayItems.size()-1 && displayItems.get(pos+1).inset;
int pad;
if(holder instanceof MediaGridStatusDisplayItem.Holder || holder instanceof LinkCardStatusDisplayItem.Holder)
// if(holder instanceof MediaGridStatusDisplayItem.Holder || holder instanceof LinkCardStatusDisplayItem.Holder)
pad=V.dp(16);
else
pad=V.dp(12);
// else
// pad=V.dp(12);
boolean insetLeft=true, insetRight=true;
if(insetLeft)
outRect.left=pad;
@@ -97,7 +97,7 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
// had to comment this out because animations with offsets aren't handled properly.
// can be worked around by manually applying top margins to items
// see InsetDummyStatusDisplayItem#onBinds
// see InsetDummyStatusDisplayItem#onBind
// if(!topSiblingInset)
// outRect.top=pad;
// if(!bottomSiblingInset)

View File

@@ -1028,13 +1028,11 @@ public class UiUtils {
return back;
}
public static boolean setExtraTextInfo(Context ctx, TextView extraText, TextView pronouns, boolean mentionedOnly, boolean localOnly, @Nullable Account account) {
public static boolean setExtraTextInfo(Context ctx, TextView extraText, TextView pronouns, boolean displayPronouns, boolean mentionedOnly, boolean localOnly, @Nullable Account account) {
List<String> extraParts = new ArrayList<>();
Optional<String> p=pronouns==null ? Optional.empty() : extractPronouns(ctx, account);
boolean setPronouns=false;
Optional<String> p=pronouns==null || !displayPronouns ? Optional.empty() : extractPronouns(ctx, account);
if(p.isPresent()) {
HtmlParser.setTextWithCustomEmoji(pronouns, p.get(), account.emojis);
setPronouns=true;
pronouns.setVisibility(View.VISIBLE);
}else if(pronouns!=null){
pronouns.setVisibility(View.GONE);
@@ -1586,7 +1584,7 @@ public class UiUtils {
private static String extractPronounsFromField(String localizedPronouns, AccountField field) {
if(!field.name.toLowerCase().contains(localizedPronouns) &&
!field.name.toLowerCase().contains("pronouns")) return null;
String text=HtmlParser.strip(field.value);
String text=HtmlParser.text(field.value);
if(field.value.toLowerCase().contains("https://")){
for(String pronounUrl : pronounsUrls){
int index=text.indexOf(pronounUrl);

View File

@@ -74,10 +74,17 @@ public class ComposePollViewController{
pollWrap=view.findViewById(R.id.poll_wrap);
Instance instance=fragment.instance;
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0)
maxPollOptions=instance.configuration.polls.maxOptions;
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0)
maxPollOptionLength=instance.configuration.polls.maxCharactersPerOption;
if (!instance.isAkkoma()) {
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0)
maxPollOptions=instance.configuration.polls.maxOptions;
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0)
maxPollOptionLength=instance.configuration.polls.maxCharactersPerOption;
} else {
if (instance.pollLimits!=null && instance.pollLimits.maxOptions>0)
maxPollOptions=instance.pollLimits.maxOptions;
if(instance.pollLimits!=null && instance.pollLimits.maxOptionChars>0)
maxPollOptionLength=instance.pollLimits.maxOptionChars;
}
pollOptionsView=pollWrap.findViewById(R.id.poll_options);
addPollOptionBtn=pollWrap.findViewById(R.id.add_poll_option);

View File

@@ -21,6 +21,7 @@ import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
import org.joinmastodon.android.api.session.AccountSessionManager;
@@ -124,7 +125,8 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
}
// you know what's cooler than followers or verified links? yep. pronouns
Optional<String> pronounsString = UiUtils.extractPronouns(itemView.getContext(), item.account);
Optional<String> pronounsString=GlobalUserPreferences.displayPronounsInUserListings
? UiUtils.extractPronouns(itemView.getContext(), item.account) : Optional.empty();
pronouns.setVisibility(pronounsString.isPresent() ? View.VISIBLE : View.GONE);
pronounsString.ifPresent(p -> HtmlParser.setTextWithCustomEmoji(pronouns, p, item.account.emojis));

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?colorM3OnSurfaceVariant" android:state_enabled="false" />
<item android:color="?colorM3OnSurfaceVariant" android:state_selected="false" />
<item android:color="?colorM3OnSurface" />
</selector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:pathData="M63.26,36.4C67.49,37.02 71.06,40.24 71.61,44.32C71.85,46.75 71.73,50.4 71.67,52.17C71.65,52.61 71.64,52.94 71.64,53.1C71.64,53.34 71.61,55.51 71.6,55.74C71.22,61.58 67.58,63.88 63.75,64.62C63.7,64.63 63.66,64.64 63.61,64.65C63.6,64.65 63.58,64.65 63.57,64.65C61.14,65.13 58.54,65.25 56.07,65.32C55.48,65.34 54.89,65.34 54.3,65.34C51.85,65.34 49.4,65.05 47.01,64.47C47,64.47 46.99,64.47 46.97,64.47C46.96,64.48 46.95,64.48 46.94,64.49C46.93,64.5 46.92,64.51 46.92,64.52C46.91,64.53 46.91,64.55 46.91,64.56C46.98,65.33 47.14,66.1 47.41,66.83C47.74,67.68 48.9,69.71 53.19,69.71C55.69,69.71 58.17,69.42 60.6,68.84C60.61,68.84 60.63,68.84 60.64,68.84C60.65,68.85 60.66,68.85 60.67,68.86C60.68,68.87 60.69,68.88 60.7,68.89C60.7,68.9 60.7,68.91 60.7,68.93V71.79C60.7,71.8 60.7,71.82 60.69,71.83C60.69,71.84 60.68,71.85 60.67,71.86C59.91,72.41 58.89,72.73 58,73.01C57.96,73.02 57.91,73.04 57.88,73.05C57.47,73.18 57.06,73.29 56.64,73.39C52.85,74.25 48.9,74.04 45.22,72.79C41.79,71.58 38.28,68.64 37.42,65.1C36.95,63.18 36.63,61.23 36.44,59.27C36.25,57.12 36.18,54.97 36.11,52.82C36.09,52.01 36.06,51.2 36.03,50.38C35.95,48.32 36,46.06 36.44,44.03C37.35,39.89 41.1,37 45.21,36.4C45.3,36.38 45.39,36.37 45.5,36.35C46.31,36.21 48.01,35.91 53.53,35.91H53.58C59.84,35.91 62.55,36.29 63.26,36.4ZM65.39,58.94V48.84C65.39,46.78 64.86,45.14 63.81,43.93C62.71,42.72 61.29,42.09 59.51,42.09C57.47,42.09 55.92,42.88 54.88,44.45L53.88,46.12L52.88,44.45C51.85,42.88 50.3,42.09 48.25,42.09C46.47,42.09 45.05,42.72 43.96,43.93C42.9,45.14 42.37,46.78 42.37,48.84V58.94H46.38V49.14C46.38,47.08 47.25,46.03 48.99,46.03C50.92,46.03 51.89,47.27 51.89,49.73V55.09H55.87V49.73C55.87,47.27 56.84,46.03 58.76,46.03C60.52,46.03 61.38,47.08 61.38,49.14V58.94H65.39Z"
android:fillColor="#4A454E"
android:fillType="evenOdd"/>
</vector>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#B2000000"/>
<solid android:color="#69000000"/>
<corners android:radius="4dp"/>
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#D0000000"/>
<corners android:radius="4dp"/>
</shape>

View File

@@ -1,21 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<ripple
android:color="@color/m3_on_surface_variant_overlay"
android:radius="42dp" />
</item>
<item>
<selector>
<item android:state_selected="true">
<layer-list>
<item android:gravity="center" android:width="28dp" android:height="28dp">
<shape android:shape="oval">
<stroke android:color="?colorM3OnSecondaryContainer" android:width="2dp"/>
</shape>
</item>
</layer-list>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<layer-list>
<item android:gravity="center" android:width="28dp" android:height="28dp">
<shape android:shape="oval">
<stroke android:color="?colorM3OnSecondaryContainer" android:width="2dp"/>
</shape>
</item>
</selector>
</layer-list>
</item>
</layer-list>
</selector>

View File

@@ -2,4 +2,4 @@
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/m3_on_surface_variant_overlay"
android:radius="42dp" />
android:radius="56dp" />

View File

@@ -24,7 +24,7 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorGray25"
android:textColor="?colorM3DarkOnSurface"
android:gravity="center"
android:includeFontPadding="false"
android:paddingHorizontal="6dp"

View File

@@ -33,7 +33,7 @@
android:layout_marginEnd="4dp"
android:importantForAccessibility="no"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:textColor="?colorM3DarkOnSurface"
android:gravity="center"
android:includeFontPadding="false"
android:background="@drawable/bg_image_alt_overlay"

View File

@@ -5,14 +5,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:layout_marginBottom="-12dp">
android:layout_marginBottom="-4dp">
<TextView
android:id="@+id/extra_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="6dp"
android:textAppearance="@style/m3_title_small"
android:textColor="?colorM3OnSurface"
android:drawableStart="@drawable/ic_fluent_arrow_reply_20sp_filled"
@@ -40,7 +39,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="6dp"
android:textAppearance="@style/m3_title_small"
android:textColor="?colorM3OnSurface"
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_20_filled"

View File

@@ -34,7 +34,7 @@
android:layout_marginEnd="4dp"
android:importantForAccessibility="no"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:textColor="?colorM3DarkOnSurface"
android:gravity="center"
android:includeFontPadding="false"
android:background="@drawable/bg_image_alt_overlay"

View File

@@ -7,7 +7,7 @@
android:layout_gravity="end|bottom"
android:layout_margin="12dp"
android:importantForAccessibility="noHideDescendants"
android:background="@drawable/bg_image_alt_overlay">
android:background="@drawable/bg_image_alt_text_overlay">
<ImageView
android:id="@+id/no_alt_button"
@@ -22,7 +22,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorGray25"
android:textColor="?colorM3DarkOnSurface"
android:gravity="center"
android:includeFontPadding="false"
android:paddingHorizontal="6dp"
@@ -36,7 +36,7 @@
android:layout_height="40dp"
android:layout_gravity="end|top"
android:src="@drawable/ic_baseline_close_24"
android:tint="#FFF"
android:tint="?colorM3DarkOnSurface"
android:background="?android:actionBarItemBackground"/>
<org.joinmastodon.android.ui.views.NestableScrollView
@@ -58,7 +58,7 @@
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:textAppearance="@style/m3_body_medium"
android:textColor="#FFF"
android:textColor="?colorM3DarkOnSurface"
tools:text="Alt text goes here"/>
<TextView
@@ -69,7 +69,7 @@
android:layout_marginEnd="8dp"
android:layout_marginStart="14dp"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorGray25"
android:textColor="?colorM3DarkOnSurface"
android:text="@string/sk_no_alt_text"/>
</LinearLayout>

View File

@@ -12,110 +12,187 @@
<org.joinmastodon.android.ui.views.TabBar
android:id="@+id/tabbar"
android:layout_width="match_parent"
android:layout_height="56dp">
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="16dp"
android:paddingHorizontal="8dp">
<FrameLayout
<LinearLayout
android:id="@+id/tab_home"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/home_timeline">
android:orientation="vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:scaleType="center"
android:importantForAccessibility="no"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_home_24_selector"/>
<FrameLayout
android:id="@+id/tab_home_pill"
android:layout_width="match_parent"
android:layout_height="32dp"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/home_timeline">
</FrameLayout>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:scaleType="center"
android:importantForAccessibility="no"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_home_24_selector"/>
<FrameLayout
</FrameLayout>
<TextView
android:id="@+id/tab_home_label"
style="@style/m3_label_medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:textColor="@color/m3_on_surface_selector"
android:text="@string/sk_tab_home" />
</LinearLayout>
<LinearLayout
android:id="@+id/tab_search"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/search_hint">
android:orientation="vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:scaleType="center"
android:importantForAccessibility="no"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_search_24_selector"/>
<FrameLayout
android:id="@+id/tab_search_pill"
android:layout_width="match_parent"
android:layout_height="32dp"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/search_hint">
</FrameLayout>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:scaleType="center"
android:importantForAccessibility="no"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_search_24_selector"/>
<RelativeLayout
</FrameLayout>
<TextView
android:id="@+id/tab_search_label"
style="@style/m3_label_medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/m3_on_surface_selector"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:text="@string/sk_tab_search" />
</LinearLayout>
<LinearLayout
android:id="@+id/tab_notifications"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/notifications">
android:orientation="vertical">
<RelativeLayout
android:id="@+id/tab_notifications_pill"
android:layout_width="match_parent"
android:layout_height="32dp"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/notifications">
<ImageView
android:id="@+id/notifications_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerInParent="true"
android:scaleType="center"
android:importantForAccessibility="no"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_alert_24_selector"/>
<TextView
android:id="@+id/notifications_badge"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:layout_gravity="center"
android:layout_alignTop="@id/notifications_icon"
android:layout_toEndOf="@id/notifications_icon"
android:layout_marginTop="-4dp"
android:layout_marginStart="-12dp"
android:background="@drawable/bg_tabbar_badge"
android:textColor="?colorM3OnPrimary"
android:gravity="center"
android:includeFontPadding="false"
android:textAppearance="@style/m3_label_small"
android:minWidth="16dp"
tools:text="222"/>
</RelativeLayout>
<ImageView
android:id="@+id/notifications_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerInParent="true"
android:scaleType="center"
android:importantForAccessibility="no"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_alert_24_selector"/>
<TextView
android:id="@+id/notifications_badge"
android:id="@+id/tab_notifications_label"
style="@style/m3_label_medium"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:layout_gravity="center"
android:layout_alignTop="@id/notifications_icon"
android:layout_toEndOf="@id/notifications_icon"
android:layout_marginTop="-4dp"
android:layout_marginStart="-12dp"
android:background="@drawable/bg_tabbar_badge"
android:textColor="?colorM3OnPrimary"
android:gravity="center"
android:includeFontPadding="false"
android:textAppearance="@style/m3_label_small"
android:minWidth="16dp"
tools:text="222"/>
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:textColor="@color/m3_on_surface_selector"
android:text="@string/sk_tab_notifications" />
</RelativeLayout>
</LinearLayout>
<FrameLayout
<LinearLayout
android:id="@+id/tab_profile"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/my_profile">
<ImageView
android:id="@+id/tab_profile_ava"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:src="@null"/>
<ImageView
android:layout_width="8dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:layout_marginStart="22dp"
android:importantForAccessibility="no"
android:scaleType="center"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_chevron_up_down_16_regular"/>
</FrameLayout>
android:layout_marginEnd="8dp"
android:orientation="vertical">
<FrameLayout
android:id="@+id/tab_profile_pill"
android:layout_width="match_parent"
android:layout_height="32dp"
android:background="@drawable/bg_tabbar_tab"
android:contentDescription="@string/my_profile">
<ImageView
android:id="@+id/tab_profile_ava"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:src="@null"/>
<ImageView
android:layout_width="8dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:layout_marginStart="22dp"
android:importantForAccessibility="no"
android:scaleType="center"
android:tint="@color/tab_bar_icon"
android:src="@drawable/ic_fluent_chevron_up_down_16_regular"/>
</FrameLayout>
<TextView
android:id="@+id/tab_profile_label"
style="@style/m3_label_medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:textColor="@color/m3_on_surface_selector"
android:text="@string/sk_tab_profile" />
</LinearLayout>
</org.joinmastodon.android.ui.views.TabBar>
</FrameLayout>

View File

@@ -336,4 +336,12 @@
<string name="sk_disable_pill_shaped_active_indicator">Disable pill-shaped active tab indicator</string>
<string name="sk_settings_true_black">Pitch black mode</string>
<string name="sk_search_fediverse">Search the Fediverse</string>
<string name="sk_settings_display_pronouns_in_timelines">Display pronouns in timelines</string>
<string name="sk_settings_display_pronouns_in_threads">Display pronouns in threads</string>
<string name="sk_settings_display_pronouns_in_user_listings">Display pronouns in user listings</string>
<string name="sk_tab_home">Home</string>
<string name="sk_tab_search">Search</string>
<string name="sk_tab_notifications">Notifications</string>
<string name="sk_tab_profile">Profile</string>
<string name="sk_settings_show_labels_in_navigation_bar">Show tab labels in the navigation bar</string>
</resources>

View File

@@ -341,6 +341,8 @@
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">12sp</item>
<item name="android:lineSpacingMultiplier">1.14</item>
<!-- see https://m3.material.io/styles/typography/type-scale-tokens#f5f4605d-8147-491d-8064-8f6514783f30 -->
<item name="android:letterSpacing">0.042</item>
<item name="android:lineHeight" tools:ignore="NewApi">16dp</item>
</style>