Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ad2d08e27 | ||
|
|
42658add38 | ||
|
|
b211789847 | ||
|
|
9c88183366 | ||
|
|
c76dba3a8c | ||
|
|
29bee87f2a | ||
|
|
c139f85b99 | ||
|
|
3247d4f2f5 | ||
|
|
77b2f98f17 | ||
|
|
82c6c8076a | ||
|
|
4177faa553 | ||
|
|
92ec125661 | ||
|
|
513a57663b | ||
|
|
20e7f716f1 | ||
|
|
71f92cb66c | ||
|
|
77b2abd0cb | ||
|
|
15385dd924 | ||
|
|
08847ec641 | ||
|
|
805fc5d8c7 | ||
|
|
3d7a95d336 | ||
|
|
c1869386ff | ||
|
|
7a728c52cf | ||
|
|
22f3aad538 | ||
|
|
42da6dcf48 | ||
|
|
c0f18b1f61 |
@@ -28,7 +28,7 @@ platform :android do
|
||||
build_type: "release",
|
||||
)
|
||||
upload_to_play_store(
|
||||
changes_not_sent_for_review: true,
|
||||
release_status: "draft",
|
||||
skip_upload_images: true,
|
||||
skip_upload_screenshots: true
|
||||
)
|
||||
|
||||
@@ -13,8 +13,8 @@ android {
|
||||
applicationId "org.joinmastodon.android"
|
||||
minSdk 23
|
||||
targetSdk 34
|
||||
versionCode 120
|
||||
versionName "2.7.1"
|
||||
versionCode 123
|
||||
versionName "2.7.3"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ dependencies {
|
||||
implementation 'me.grishka.litex:viewpager:1.0.0'
|
||||
implementation 'me.grishka.litex:viewpager2:1.0.0'
|
||||
implementation 'me.grishka.litex:palette:1.0.0'
|
||||
implementation 'me.grishka.appkit:appkit:1.4.1'
|
||||
implementation 'me.grishka.appkit:appkit:1.4.3'
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
implementation 'org.jsoup:jsoup:1.14.3'
|
||||
implementation 'com.squareup:otto:1.3.8'
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="http" android:host="*"/>
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<data android:scheme="https" android:host="*"/>
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
|
||||
@@ -295,6 +295,15 @@ public class CacheController{
|
||||
.collect(Collectors.toList());
|
||||
PaginatedResponse<List<NotificationViewModel>> res=new PaginatedResponse<>(converted, result.isEmpty() ? null : result.get(result.size()-1).id);
|
||||
callback.onSuccess(res);
|
||||
if(!onlyMentions){
|
||||
loadingNotifications=false;
|
||||
synchronized(pendingNotificationsCallbacks){
|
||||
for(Callback<PaginatedResponse<List<NotificationViewModel>>> cb:pendingNotificationsCallbacks){
|
||||
cb.onSuccess(res);
|
||||
}
|
||||
pendingNotificationsCallbacks.clear();
|
||||
}
|
||||
}
|
||||
databaseThread.postRunnable(()->putNotifications(converted.stream().map(nvm->nvm.notification).collect(Collectors.toList()), accounts, statuses, onlyMentions, maxID==null), 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
package org.joinmastodon.android.api.requests.notifications;
|
||||
|
||||
import org.joinmastodon.android.api.ApiUtils;
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.NotificationType;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class GetUnreadNotificationsCount extends MastodonAPIRequest<GetUnreadNotificationsCount.Response>{
|
||||
public GetUnreadNotificationsCount(){
|
||||
public GetUnreadNotificationsCount(EnumSet<NotificationType> includeTypes, EnumSet<NotificationType> groupedTypes){
|
||||
super(HttpMethod.GET, "/notifications/unread_count", Response.class);
|
||||
if(includeTypes!=null){
|
||||
for(String type: ApiUtils.enumSetToStrings(includeTypes, NotificationType.class)){
|
||||
addQueryParameter("types[]", type);
|
||||
}
|
||||
for(String type:ApiUtils.enumSetToStrings(EnumSet.complementOf(includeTypes), NotificationType.class)){
|
||||
addQueryParameter("exclude_types[]", type);
|
||||
}
|
||||
}
|
||||
if(groupedTypes!=null){
|
||||
for(String type:ApiUtils.enumSetToStrings(groupedTypes, NotificationType.class)){
|
||||
addQueryParameter("grouped_types[]", type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -84,7 +84,7 @@ public class CreateListAddMembersFragment extends BaseAccountListFragment implem
|
||||
public void onSuccess(HeaderPaginationList<Account> result){
|
||||
for(Account acc:result)
|
||||
accountIDsInList.add(acc.id);
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID)).collect(Collectors.toList()));
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID, getActivity())).collect(Collectors.toList()));
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
|
||||
@@ -296,7 +296,7 @@ public class HomeFragment extends AppKitFragment{
|
||||
if(instance==null)
|
||||
return;
|
||||
if(instance.getApiVersion()>=2){
|
||||
new GetUnreadNotificationsCount()
|
||||
new GetUnreadNotificationsCount(EnumSet.allOf(NotificationType.class), NotificationType.getGroupableTypes())
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(GetUnreadNotificationsCount.Response result){
|
||||
|
||||
@@ -190,7 +190,7 @@ public class ListMembersFragment extends PaginatedAccountListFragment implements
|
||||
@Subscribe
|
||||
public void onAccountAddedToList(AccountAddedToListEvent ev){
|
||||
if(ev.accountID.equals(accountID) && ev.listID.equals(followList.id)){
|
||||
data.add(new AccountViewModel(ev.account, accountID));
|
||||
data.add(new AccountViewModel(ev.account, accountID, getActivity()));
|
||||
list.getAdapter().notifyItemInserted(data.size()-1);
|
||||
}
|
||||
}
|
||||
@@ -337,7 +337,7 @@ public class ListMembersFragment extends PaginatedAccountListFragment implements
|
||||
onDone.run();
|
||||
for(Account acc:accounts){
|
||||
accountIDsInList.add(acc.id);
|
||||
data.add(new AccountViewModel(acc, accountID));
|
||||
data.add(new AccountViewModel(acc, accountID, getActivity()));
|
||||
}
|
||||
list.getAdapter().notifyItemRangeInserted(data.size()-accounts.size(), accounts.size());
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public class NotificationRequestsFragment extends MastodonRecyclerFragment<Notif
|
||||
accountViewModels.clear();
|
||||
maxID=result.getNextPageMaxID();
|
||||
for(NotificationRequest req:result){
|
||||
accountViewModels.put(req.account.id, new AccountViewModel(req.account, accountID, false));
|
||||
accountViewModels.put(req.account.id, new AccountViewModel(req.account, accountID, false, getActivity()));
|
||||
}
|
||||
onDataLoaded(result, !TextUtils.isEmpty(maxID));
|
||||
endMark.setVisibility(TextUtils.isEmpty(maxID) ? View.VISIBLE : View.GONE);
|
||||
|
||||
@@ -241,7 +241,7 @@ public class NotificationsListFragment extends BaseNotificationsListFragment{
|
||||
public boolean onOptionsItemSelected(MenuItem item){
|
||||
int id=item.getItemId();
|
||||
if(id==R.id.mark_all_read){
|
||||
markAsRead();
|
||||
markAsRead(true);
|
||||
resetUnreadBackground();
|
||||
}else if(id==R.id.filters){
|
||||
showFiltersAlert();
|
||||
@@ -257,11 +257,11 @@ public class NotificationsListFragment extends BaseNotificationsListFragment{
|
||||
return mergeAdapter;
|
||||
}
|
||||
|
||||
private void markAsRead(){
|
||||
private void markAsRead(boolean force){
|
||||
if(data.isEmpty())
|
||||
return;
|
||||
String id=data.get(0).notification.pageMaxId;
|
||||
if(ObjectIdComparator.INSTANCE.compare(id, realUnreadMarker)>0){
|
||||
if(force || ObjectIdComparator.INSTANCE.compare(id, realUnreadMarker)>0){
|
||||
new SaveMarkers(null, id).exec(accountID);
|
||||
AccountSessionManager.get(accountID).setNotificationsMarker(id, true);
|
||||
realUnreadMarker=id;
|
||||
@@ -290,7 +290,7 @@ public class NotificationsListFragment extends BaseNotificationsListFragment{
|
||||
return;
|
||||
for(NotificationViewModel n:items){
|
||||
if(ObjectIdComparator.INSTANCE.compare(n.notification.pageMinId, realUnreadMarker)<=0){
|
||||
markAsRead();
|
||||
markAsRead(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +580,7 @@ public class ProfileFragment extends LoaderFragment implements ScrollableToTop{
|
||||
domain=AccountSessionManager.get(accountID).domain;
|
||||
usernameDomain.setText(domain);
|
||||
|
||||
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account);
|
||||
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account, getActivity());
|
||||
if(TextUtils.isEmpty(parsedBio)){
|
||||
bio.setVisibility(View.GONE);
|
||||
}else{
|
||||
@@ -615,7 +615,7 @@ public class ProfileFragment extends LoaderFragment implements ScrollableToTop{
|
||||
fields.add(joined);
|
||||
|
||||
for(AccountField field:account.fields){
|
||||
field.parsedValue=ssb=HtmlParser.parse(field.value, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account);
|
||||
field.parsedValue=ssb=HtmlParser.parse(field.value, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account, getActivity());
|
||||
field.valueEmojis=ssb.getSpans(0, ssb.length(), CustomEmojiSpan.class);
|
||||
ssb=new SpannableStringBuilder(field.name);
|
||||
HtmlParser.parseCustomEmoji(ssb, account.emojis);
|
||||
|
||||
@@ -236,6 +236,8 @@ public class ThreadFragment extends StatusListFragment{
|
||||
protected void drawDivider(View child, View bottomSibling, RecyclerView.ViewHolder holder, RecyclerView.ViewHolder siblingHolder, RecyclerView parent, Canvas c, Paint paint){
|
||||
if(holder instanceof StatusDisplayItem.Holder<?> statusHolder && siblingHolder instanceof StatusDisplayItem.Holder<?> siblingStatusHolder){
|
||||
Status siblingStatus=getStatusByID(siblingStatusHolder.getItemID());
|
||||
if(siblingStatus==null)
|
||||
return;
|
||||
if(statusHolder.getItemID().equals(siblingStatus.inReplyToId) && siblingStatus!=mainStatus && !statusHolder.getItemID().equals(mainStatus.id))
|
||||
return;
|
||||
}
|
||||
@@ -291,6 +293,7 @@ public class ThreadFragment extends StatusListFragment{
|
||||
continue;
|
||||
|
||||
float lineX=V.dp(36);
|
||||
paint.setAlpha(Math.round(255*child.getAlpha()));
|
||||
c.save();
|
||||
c.clipRect(child.getX(), child.getY(), child.getX()+child.getWidth(), child.getY()+child.getHeight());
|
||||
if(holder instanceof HeaderStatusDisplayItem.Holder){
|
||||
|
||||
@@ -61,7 +61,7 @@ public class AccountSearchFragment extends BaseAccountListFragment{
|
||||
|
||||
protected void onSuccess(List<Account> result){
|
||||
setEmptyText(R.string.no_search_results);
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID)).collect(Collectors.toList()), false);
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID, getActivity())).collect(Collectors.toList()), false);
|
||||
}
|
||||
|
||||
protected String getSearchViewPlaceholder(){
|
||||
|
||||
@@ -44,7 +44,7 @@ public class AddNewListMembersFragment extends AccountSearchFragment{
|
||||
@Override
|
||||
public void onSuccess(HeaderPaginationList<Account> result){
|
||||
setEmptyText("");
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID)).collect(Collectors.toList()), result.nextPageUri!=null);
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID, getActivity())).collect(Collectors.toList()), result.nextPageUri!=null);
|
||||
maxID=result.getNextPageMaxID();
|
||||
}
|
||||
})
|
||||
|
||||
@@ -24,7 +24,7 @@ public abstract class PaginatedAccountListFragment extends BaseAccountListFragme
|
||||
nextMaxID=result.nextPageUri.getQueryParameter("max_id");
|
||||
else
|
||||
nextMaxID=null;
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID)).collect(Collectors.toList()), nextMaxID!=null);
|
||||
onDataLoaded(result.stream().map(a->new AccountViewModel(a, accountID, getActivity())).collect(Collectors.toList()), nextMaxID!=null);
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
|
||||
@@ -31,7 +31,7 @@ public class DiscoverAccountsFragment extends BaseAccountListFragment implements
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(List<FollowSuggestion> result){
|
||||
List<AccountViewModel> accounts=result.stream().map(fs->new AccountViewModel(fs.account, accountID)).collect(Collectors.toList());
|
||||
List<AccountViewModel> accounts=result.stream().map(fs->new AccountViewModel(fs.account, accountID, getActivity())).collect(Collectors.toList());
|
||||
onDataLoaded(accounts, false);
|
||||
bannerHelper.onBannerBecameVisible();
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
return;
|
||||
|
||||
onDataLoaded(results.stream().map(sr->{
|
||||
SearchResultViewModel vm=new SearchResultViewModel(sr, accountID, true);
|
||||
SearchResultViewModel vm=new SearchResultViewModel(sr, accountID, true, getActivity());
|
||||
if(sr.type==SearchResult.Type.HASHTAG){
|
||||
vm.hashtagItem.setOnClick(i->openHashtag(sr));
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
onDataLoaded(Stream.of(result.hashtags.stream().map(SearchResult::new), result.accounts.stream().map(SearchResult::new))
|
||||
.flatMap(Function.identity())
|
||||
.map(sr->{
|
||||
SearchResultViewModel vm=new SearchResultViewModel(sr, accountID, false);
|
||||
SearchResultViewModel vm=new SearchResultViewModel(sr, accountID, false, getActivity());
|
||||
if(sr.type==SearchResult.Type.HASHTAG){
|
||||
vm.hashtagItem.setOnClick(i->openHashtag(sr));
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class OnboardingFollowSuggestionsFragment extends BaseAccountListFragment
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(List<FollowSuggestion> result){
|
||||
onDataLoaded(result.stream().map(fs->new AccountViewModel(fs.account, accountID).stripLinksFromBio()).collect(Collectors.toList()), false);
|
||||
onDataLoaded(result.stream().map(fs->new AccountViewModel(fs.account, accountID, getActivity()).stripLinksFromBio()).collect(Collectors.toList()), false);
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
|
||||
@@ -128,7 +128,7 @@ public class SettingsServerAboutFragment extends LoaderFragment{
|
||||
hlp.leftMargin=hlp.rightMargin=V.dp(16);
|
||||
scrollingLayout.addView(heading, hlp);
|
||||
|
||||
AccountViewModel model=new AccountViewModel(instance.getContactAccount(), accountID);
|
||||
AccountViewModel model=new AccountViewModel(instance.getContactAccount(), accountID, getActivity());
|
||||
AccountViewHolder holder=new AccountViewHolder(this, scrollingLayout, null);
|
||||
holder.setStyle(AccountViewHolder.AccessoryType.NONE, false);
|
||||
holder.bind(model);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.joinmastodon.android.model.viewmodel;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
||||
@@ -24,11 +25,11 @@ public class AccountViewModel{
|
||||
public final CharSequence parsedName, parsedBio;
|
||||
public final String verifiedLink;
|
||||
|
||||
public AccountViewModel(Account account, String accountID){
|
||||
this(account, accountID, true);
|
||||
public AccountViewModel(Account account, String accountID, Context context){
|
||||
this(account, accountID, true, context);
|
||||
}
|
||||
|
||||
public AccountViewModel(Account account, String accountID, boolean needBio){
|
||||
public AccountViewModel(Account account, String accountID, boolean needBio, Context context){
|
||||
this.account=account;
|
||||
avaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(50), V.dp(50));
|
||||
emojiHelper=new CustomEmojiHelper();
|
||||
@@ -38,7 +39,7 @@ public class AccountViewModel{
|
||||
parsedName=account.displayName;
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(parsedName);
|
||||
if(needBio){
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account);
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account, context);
|
||||
ssb.append(parsedBio);
|
||||
}else{
|
||||
parsedBio=null;
|
||||
|
||||
@@ -11,10 +11,10 @@ public class SearchResultViewModel{
|
||||
public AccountViewModel account;
|
||||
public ListItem<Hashtag> hashtagItem;
|
||||
|
||||
public SearchResultViewModel(SearchResult result, String accountID, boolean isRecents){
|
||||
public SearchResultViewModel(SearchResult result, String accountID, boolean isRecents, Context context){
|
||||
this.result=result;
|
||||
switch(result.type){
|
||||
case ACCOUNT -> account=new AccountViewModel(result.account, accountID);
|
||||
case ACCOUNT -> account=new AccountViewModel(result.account, accountID, context);
|
||||
case HASHTAG -> {
|
||||
hashtagItem=new ListItem<>((isRecents ? "#" : "")+result.hashtag.name, null, isRecents ? R.drawable.ic_history_24px : R.drawable.ic_tag_24px, null, result.hashtag);
|
||||
hashtagItem.isEnabled=true;
|
||||
|
||||
@@ -15,7 +15,7 @@ public class AccountStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
public AccountStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Account account){
|
||||
super(parentID, parentFragment);
|
||||
this.account=new AccountViewModel(account, parentFragment.getAccountID());
|
||||
this.account=new AccountViewModel(account, parentFragment.getAccountID(), parentFragment.getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,7 +39,7 @@ public class InlineStatusStatusDisplayItem extends StatusDisplayItem{
|
||||
if(AccountSessionManager.get(parentFragment.getAccountID()).getLocalPreferences().customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(parsedName, status.account.emojis);
|
||||
|
||||
parsedPostText=HtmlParser.parse(status.content, status.emojis, status.mentions, status.tags, parentFragment.getAccountID(), status.getContentStatus());
|
||||
parsedPostText=HtmlParser.parse(status.content, status.emojis, status.mentions, status.tags, parentFragment.getAccountID(), status.getContentStatus(), parentFragment.getActivity());
|
||||
for(Object span:parsedPostText.getSpans(0, parsedPostText.length(), Object.class)){
|
||||
if(!(span instanceof CustomEmojiSpan))
|
||||
parsedPostText.removeSpan(span);
|
||||
|
||||
@@ -141,7 +141,7 @@ public abstract class StatusDisplayItem{
|
||||
}
|
||||
|
||||
if(!TextUtils.isEmpty(statusForContent.content)){
|
||||
SpannableStringBuilder parsedText=HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID, statusForContent);
|
||||
SpannableStringBuilder parsedText=HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID, statusForContent, fragment.getActivity());
|
||||
if(filtered){
|
||||
HtmlParser.applyFilterHighlights(fragment.getActivity(), parsedText, status.filtered);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
public void setTranslatedText(String text){
|
||||
Status statusForContent=status.getContentStatus();
|
||||
translatedText=HtmlParser.parse(text, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, parentFragment.getAccountID(), statusForContent);
|
||||
translatedText=HtmlParser.parse(text, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, parentFragment.getAccountID(), statusForContent, parentFragment.getActivity());
|
||||
translationEmojiHelper.setText(translatedText);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.joinmastodon.android.ui.text;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.TypefaceSpan;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public abstract class BaseMonospaceSpan extends TypefaceSpan{
|
||||
private final Context context;
|
||||
|
||||
public BaseMonospaceSpan(Context context){
|
||||
super("monospace");
|
||||
this.context=context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(@NonNull TextPaint paint){
|
||||
super.updateDrawState(paint);
|
||||
paint.setColor(UiUtils.getThemeColor(context, R.attr.colorRichTextText));
|
||||
paint.setTextSize(paint.getTextSize()*0.9375f);
|
||||
paint.baselineShift=V.dp(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMeasureState(@NonNull TextPaint paint){
|
||||
super.updateMeasureState(paint);
|
||||
paint.setTextSize(paint.getTextSize()*0.9375f);
|
||||
paint.baselineShift=V.dp(-1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.joinmastodon.android.ui.text;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.LeadingMarginSpan;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class BlockQuoteSpan extends CharacterStyle implements LeadingMarginSpan{
|
||||
private final Context context;
|
||||
private Drawable icon;
|
||||
private boolean firstLevel;
|
||||
private Paint paint=new Paint();
|
||||
|
||||
public BlockQuoteSpan(Context context, boolean firstLevel){
|
||||
this.context=context;
|
||||
icon=context.getResources().getDrawable(R.drawable.quote, context.getTheme()).mutate();
|
||||
this.firstLevel=firstLevel;
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(V.dp(3));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getLeadingMargin(boolean first){
|
||||
return V.dp(firstLevel ? 32 : 18);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLeadingMargin(@NonNull Canvas c, @NonNull Paint p, int x, int dir, int top, int baseline, int bottom, @NonNull CharSequence text, int start, int end, boolean first, @NonNull Layout layout){
|
||||
if(text instanceof Spanned s && s.getSpanStart(this)==start){
|
||||
int color;
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S && UiUtils.isDarkTheme()){
|
||||
color=UiUtils.alphaBlendColors(
|
||||
context.getColor(android.R.color.system_accent3_700),
|
||||
context.getColor(android.R.color.system_accent3_800),
|
||||
0.5f
|
||||
);
|
||||
}else{
|
||||
color=UiUtils.getThemeColor(context, R.attr.colorRichTextDecorations);
|
||||
}
|
||||
int level=s.getSpans(start, end, LeadingMarginSpan.class).length-1;
|
||||
if(dir<0){ // RTL
|
||||
if(level==0){
|
||||
icon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
icon.setBounds(layout.getWidth()-icon.getIntrinsicWidth(), top, layout.getWidth(), top+icon.getIntrinsicHeight());
|
||||
icon.draw(c);
|
||||
}else{
|
||||
paint.setColor(color);
|
||||
float xOffset=layout.getWidth()-V.dp(32+18*(level-1)+1.5f);
|
||||
c.drawLine(xOffset, top, xOffset, layout.getLineBottom(layout.getLineForOffset(s.getSpanEnd(this))), paint);
|
||||
}
|
||||
}else{
|
||||
if(level==0){
|
||||
icon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
icon.setBounds(x, top, x+icon.getIntrinsicWidth(), top+icon.getIntrinsicHeight());
|
||||
icon.draw(c);
|
||||
}else{
|
||||
paint.setColor(color);
|
||||
float xOffset=x+V.dp(32+18*(level-1)+1.5f);
|
||||
c.drawLine(xOffset, top, xOffset, layout.getLineBottom(layout.getLineForOffset(s.getSpanEnd(this))), paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(TextPaint tp){
|
||||
tp.setColor(UiUtils.getThemeColor(context, R.attr.colorRichTextText));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.joinmastodon.android.ui.text;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class CodeBlockSpan extends BaseMonospaceSpan{
|
||||
public CodeBlockSpan(Context context){
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
package org.joinmastodon.android.ui.text;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.BackgroundColorSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.LineHeightSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StrikethroughSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.twitter.twittertext.Regex;
|
||||
@@ -34,6 +40,7 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class HtmlParser{
|
||||
private static final String TAG="HtmlParser";
|
||||
@@ -69,7 +76,7 @@ public class HtmlParser{
|
||||
* @param emojis Custom emojis that are present in source as <code>:code:</code>
|
||||
* @return a spanned string
|
||||
*/
|
||||
public static SpannableStringBuilder parse(String source, List<Emoji> emojis, List<Mention> mentions, List<Hashtag> tags, String accountID, Object parentObject){
|
||||
public static SpannableStringBuilder parse(String source, List<Emoji> emojis, List<Mention> mentions, List<Hashtag> tags, String accountID, Object parentObject, Context context){
|
||||
class SpanInfo{
|
||||
public Object span;
|
||||
public int start;
|
||||
@@ -92,10 +99,34 @@ public class HtmlParser{
|
||||
Jsoup.parseBodyFragment(source).body().traverse(new NodeVisitor(){
|
||||
private final ArrayList<SpanInfo> openSpans=new ArrayList<>();
|
||||
|
||||
private boolean isInsidePre(){
|
||||
for(SpanInfo si:openSpans){
|
||||
if(si.span instanceof CodeBlockSpan)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInsideBlockquote(){
|
||||
for(SpanInfo si:openSpans){
|
||||
if(si.span instanceof BlockQuoteSpan)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@Override
|
||||
public void head(@NonNull Node node, int depth){
|
||||
if(node instanceof TextNode textNode){
|
||||
ssb.append(textNode.text());
|
||||
if(isInsidePre()){
|
||||
ssb.append(textNode.getWholeText().stripTrailing());
|
||||
}else{
|
||||
String text=textNode.text();
|
||||
if(ssb.length()==0 || ssb.charAt(ssb.length()-1)=='\n')
|
||||
text=text.stripLeading();
|
||||
ssb.append(text);
|
||||
}
|
||||
}else if(node instanceof Element el){
|
||||
switch(el.nodeName()){
|
||||
case "a" -> {
|
||||
@@ -131,6 +162,44 @@ public class HtmlParser{
|
||||
openSpans.add(new SpanInfo(new InvisibleSpan(), ssb.length(), el));
|
||||
}
|
||||
}
|
||||
case "b", "strong" -> openSpans.add(new SpanInfo(new StyleSpan(Typeface.BOLD), ssb.length(), el));
|
||||
case "i", "em" -> openSpans.add(new SpanInfo(new StyleSpan(Typeface.ITALIC), ssb.length(), el));
|
||||
case "s", "del" -> openSpans.add(new SpanInfo(new StrikethroughSpan(), ssb.length(), el));
|
||||
case "code" -> {
|
||||
if(!isInsidePre()){
|
||||
openSpans.add(new SpanInfo(new MonospaceSpan(context), ssb.length(), el));
|
||||
ssb.append(" ", new SpacerSpan(V.dp(4), 0), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
case "pre" -> openSpans.add(new SpanInfo(new CodeBlockSpan(context), ssb.length(), el));
|
||||
case "li" -> {
|
||||
Element parent=el.parent();
|
||||
if(parent==null)
|
||||
return;
|
||||
|
||||
if(ssb.length()>0 && ssb.charAt(ssb.length()-1)!='\n')
|
||||
ssb.append('\n');
|
||||
String markerText;
|
||||
if("ol".equals(parent.nodeName())){
|
||||
markerText=String.format("%d.", (parent.hasAttr("start") ? safeParseInt(parent.attr("start")) : 1)+el.elementSiblingIndex());
|
||||
}else{
|
||||
markerText="•";
|
||||
}
|
||||
openSpans.add(new SpanInfo(new ListItemMarkerSpan(markerText), ssb.length(), el));
|
||||
StringBuilder copyableText=new StringBuilder();
|
||||
for(SpanInfo si:openSpans){
|
||||
if(si.span instanceof ListItemMarkerSpan ims){
|
||||
copyableText.append(ims.text);
|
||||
}
|
||||
}
|
||||
copyableText.append(' ');
|
||||
ssb.append(copyableText.toString(), new InvisibleSpan(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
case "blockquote" -> {
|
||||
if(ssb.length()>0 && ssb.charAt(ssb.length()-1)!='\n')
|
||||
ssb.append('\n');
|
||||
openSpans.add(new SpanInfo(new BlockQuoteSpan(context, !isInsideBlockquote()), ssb.length(), el));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,15 +207,27 @@ public class HtmlParser{
|
||||
@Override
|
||||
public void tail(@NonNull Node node, int depth){
|
||||
if(node instanceof Element el){
|
||||
if("span".equals(el.nodeName()) && el.hasClass("ellipsis")){
|
||||
String name=el.nodeName();
|
||||
if("span".equals(name) && el.hasClass("ellipsis")){
|
||||
ssb.append("…", new DeleteWhenCopiedSpan(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}else if("p".equals(el.nodeName())){
|
||||
}else if("p".equals(name) || "ol".equals(name) || "ul".equals(name)){
|
||||
if(node.nextSibling()!=null && "body".equals(node.parent().nodeName())){
|
||||
ssb.append('\n');
|
||||
ssb.append("\n", new SpacerSpan(1, V.dp(8)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}else if("pre".equals(name)){
|
||||
if(node.nextSibling()!=null)
|
||||
ssb.append("\n\n");
|
||||
}else if(!openSpans.isEmpty()){
|
||||
ssb.append("\n");
|
||||
}
|
||||
if(!openSpans.isEmpty()){
|
||||
SpanInfo si=openSpans.get(openSpans.size()-1);
|
||||
if(si.element==el){
|
||||
if(si.span!=null){
|
||||
if(si.span instanceof MonospaceSpan){
|
||||
ssb.append(" ", new SpacerSpan(V.dp(4), 0), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
ssb.setSpan(si.span, si.start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
openSpans.remove(openSpans.size()-1);
|
||||
}
|
||||
}
|
||||
@@ -158,6 +239,14 @@ public class HtmlParser{
|
||||
return ssb;
|
||||
}
|
||||
|
||||
private static int safeParseInt(String s){
|
||||
try{
|
||||
return Integer.parseInt(s);
|
||||
}catch(NumberFormatException x){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseCustomEmoji(SpannableStringBuilder ssb, List<Emoji> emojis){
|
||||
Map<String, Emoji> emojiByCode =
|
||||
emojis.stream()
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.joinmastodon.android.ui.text;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.text.Layout;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.LeadingMarginSpan;
|
||||
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class ListItemMarkerSpan implements LeadingMarginSpan{
|
||||
public String text;
|
||||
|
||||
public ListItemMarkerSpan(String text){
|
||||
this.text=text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeadingMargin(boolean first){
|
||||
return V.dp(32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout){
|
||||
if(text instanceof Spanned s && s.getSpanStart(this)==start){
|
||||
int level=s.getSpans(start, end, LeadingMarginSpan.class).length-1;
|
||||
if(dir<0){ // RTL
|
||||
c.drawText(this.text, layout.getWidth()-V.dp(32*level)-p.measureText(this.text), baseline, p);
|
||||
}else{
|
||||
c.drawText(this.text, x+V.dp(32*level), baseline, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.joinmastodon.android.ui.text;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class MonospaceSpan extends BaseMonospaceSpan{
|
||||
public MonospaceSpan(Context context){
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,12 @@ public class SpacerSpan extends ReplacementSpan{
|
||||
|
||||
@Override
|
||||
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm){
|
||||
// TODO height
|
||||
if(fm!=null && height>0){
|
||||
fm.ascent=-height;
|
||||
fm.descent=0;
|
||||
fm.top=fm.ascent;
|
||||
fm.bottom=0;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
@@ -713,8 +713,8 @@ public class UiUtils{
|
||||
item.setIcon(icon);
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(item.getTitle());
|
||||
ssb.insert(0, " ");
|
||||
ssb.setSpan(new SpacerSpan(V.dp(24), 1), 0, 1, 0);
|
||||
ssb.append(" ", new SpacerSpan(V.dp(8), 1), 0);
|
||||
ssb.setSpan(new SpacerSpan(V.dp(24), 0), 0, 1, 0);
|
||||
ssb.append(" ", new SpacerSpan(V.dp(8), 0), 0);
|
||||
item.setTitle(ssb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ public class ComposeAutocompleteViewController{
|
||||
if(mode!=Mode.USERS)
|
||||
return;
|
||||
List<AccountViewModel> oldList=users;
|
||||
users=result.accounts.stream().map(a->new AccountViewModel(a, accountID)).collect(Collectors.toList());
|
||||
users=result.accounts.stream().map(a->new AccountViewModel(a, accountID, activity)).collect(Collectors.toList());
|
||||
if(isLoading){
|
||||
isLoading=false;
|
||||
if(users.size()>=LOADING_FAKE_USER_COUNT){
|
||||
|
||||
@@ -4,6 +4,10 @@ import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.CornerPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.text.Layout;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.util.AttributeSet;
|
||||
@@ -14,14 +18,22 @@ import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.ui.text.ClickableLinksDelegate;
|
||||
import org.joinmastodon.android.ui.text.CodeBlockSpan;
|
||||
import org.joinmastodon.android.ui.text.DeleteWhenCopiedSpan;
|
||||
import org.joinmastodon.android.ui.text.MonospaceSpan;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class LinkedTextView extends TextView{
|
||||
|
||||
private ClickableLinksDelegate delegate=new ClickableLinksDelegate(this);
|
||||
private boolean needInvalidate;
|
||||
private ActionMode currentActionMode;
|
||||
private Paint bgPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private Path tmpPath=new Path();
|
||||
|
||||
public LinkedTextView(Context context){
|
||||
this(context, null);
|
||||
@@ -56,6 +68,8 @@ public class LinkedTextView extends TextView{
|
||||
currentActionMode=null;
|
||||
}
|
||||
});
|
||||
bgPaint.setColor(UiUtils.getThemeColor(context, R.attr.colorRichTextContainer));
|
||||
bgPaint.setPathEffect(new CornerPathEffect(V.dp(2)));
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent ev){
|
||||
@@ -64,6 +78,22 @@ public class LinkedTextView extends TextView{
|
||||
}
|
||||
|
||||
public void onDraw(Canvas c){
|
||||
if(getText() instanceof Spanned spanned){
|
||||
c.save();
|
||||
c.translate(getTotalPaddingLeft(), getTotalPaddingTop());
|
||||
Layout layout=getLayout();
|
||||
MonospaceSpan[] monospaceSpans=spanned.getSpans(0, spanned.length(), MonospaceSpan.class);
|
||||
for(MonospaceSpan span:monospaceSpans){
|
||||
layout.getSelectionPath(spanned.getSpanStart(span), spanned.getSpanEnd(span), tmpPath);
|
||||
c.drawPath(tmpPath, bgPaint);
|
||||
}
|
||||
CodeBlockSpan[] blockSpans=spanned.getSpans(0, spanned.length(), CodeBlockSpan.class);
|
||||
for(CodeBlockSpan span:blockSpans){
|
||||
c.drawRoundRect(V.dp(-4), layout.getLineTop(layout.getLineForOffset(spanned.getSpanStart(span)))-V.dp(8), layout.getWidth()+V.dp(4),
|
||||
layout.getLineBottom(layout.getLineForOffset(spanned.getSpanEnd(span)))+V.dp(4), V.dp(2), V.dp(2), bgPaint);
|
||||
}
|
||||
c.restore();
|
||||
}
|
||||
super.onDraw(c);
|
||||
delegate.onDraw(c);
|
||||
if(needInvalidate)
|
||||
|
||||
9
mastodon/src/main/res/drawable/quote.xml
Normal file
9
mastodon/src/main/res/drawable/quote.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M23.933,2.824C22.324,4.079 21.073,5.357 20.179,6.657C19.33,7.912 18.905,9.1 18.905,10.221C19.084,10.131 19.307,10.086 19.575,10.086C19.888,10.041 20.156,10.019 20.38,10.019C21.408,10.019 22.257,10.445 22.927,11.297C23.642,12.103 24,13.112 24,14.322C24,15.802 23.508,17.035 22.525,18.021C21.542,19.007 20.313,19.5 18.838,19.5C17.274,19.5 16.045,18.94 15.151,17.819C14.257,16.653 13.81,15.107 13.81,13.179C13.81,10.893 14.503,8.629 15.888,6.388C17.274,4.147 19.307,2.017 21.989,0L23.933,2.824ZM10.123,2.824C8.514,4.079 7.263,5.357 6.369,6.657C5.52,7.912 5.095,9.1 5.095,10.221C5.274,10.131 5.497,10.086 5.765,10.086C6.078,10.041 6.346,10.019 6.57,10.019C7.598,10.019 8.447,10.445 9.117,11.297C9.832,12.103 10.19,13.112 10.19,14.322C10.19,15.802 9.698,17.035 8.715,18.021C7.732,19.007 6.503,19.5 5.028,19.5C3.464,19.5 2.235,18.94 1.341,17.819C0.447,16.653 0,15.107 0,13.179C0,10.893 0.693,8.629 2.078,6.388C3.464,4.147 5.497,2.017 8.179,0L10.123,2.824Z"/>
|
||||
</vector>
|
||||
@@ -13,8 +13,8 @@
|
||||
<string name="notifications">Benachrichtigungen</string>
|
||||
<string name="user_followed_you">%s folgt dir jetzt</string>
|
||||
<string name="user_sent_follow_request">%s hat dir eine Folgeanfrage gesendet</string>
|
||||
<string name="user_favorited">%s als Favorit markiert:</string>
|
||||
<string name="notification_boosted">%s verstärkt:</string>
|
||||
<string name="user_favorited">%s favorisierte:</string>
|
||||
<string name="notification_boosted">%s teilte deinen Beitrag:</string>
|
||||
<string name="share_toot_title">Teilen</string>
|
||||
<string name="settings">Einstellungen</string>
|
||||
<string name="publish">Veröffentlichen</string>
|
||||
@@ -216,8 +216,8 @@
|
||||
<string name="followed_user">Du folgst nun %s</string>
|
||||
<string name="following_user_requested">Deine Follower-Anfrage an %s wurde gesendet</string>
|
||||
<string name="open_in_browser">Im Browser öffnen</string>
|
||||
<string name="hide_boosts_from_user">Boosts ausblenden</string>
|
||||
<string name="show_boosts_from_user">Boosts anzeigen</string>
|
||||
<string name="hide_boosts_from_user">Geteilte Beiträge ausblenden</string>
|
||||
<string name="show_boosts_from_user">Geteilte Beiträge anzeigen</string>
|
||||
<string name="signup_reason">Warum möchtest du beitreten?</string>
|
||||
<string name="signup_reason_note">Das erleichtert uns die Prüfung deiner Anmeldung.</string>
|
||||
<string name="clear">Leeren</string>
|
||||
@@ -769,7 +769,41 @@
|
||||
<string name="cant_load_image">Bild konnte nicht geladen werden</string>
|
||||
<string name="poll_see_results">Ergebnisse anzeigen</string>
|
||||
<string name="poll_hide_results">Ergebnisse verstecken</string>
|
||||
<plurals name="x_attachments">
|
||||
<item quantity="one">%d Anhang</item>
|
||||
<item quantity="other">%d Anhänge</item>
|
||||
</plurals>
|
||||
<plurals name="user_and_x_more_favorited">
|
||||
<item quantity="one">%1$s und %2$,d weitere Person favorisierten:</item>
|
||||
<item quantity="other">%1$s und %2$,d weitere Personen favorisierten:</item>
|
||||
</plurals>
|
||||
<plurals name="user_and_x_more_boosted">
|
||||
<item quantity="one">%1$s und %2$,d weitere Person haben geteilt:</item>
|
||||
<item quantity="other">%1$s und %2$,d weitere Personen haben geteilt:</item>
|
||||
</plurals>
|
||||
<plurals name="poll_ended_x_voters">
|
||||
<item quantity="one">%1$s hat eine Umfrage durchgeführt, an der du und %2$,d weitere Person teilgenommen haben</item>
|
||||
<item quantity="other">%1$s hat eine Umfrage durchgeführt, an der du und %2$,d weitere Personen teilgenommen haben</item>
|
||||
</plurals>
|
||||
<string name="own_poll_ended">Ihre Umfrage ist beendet</string>
|
||||
<string name="user_just_posted">%s hat gerade gepostet</string>
|
||||
<string name="user_edited_post">%s hat einen Beitrag bearbeitet, mit dem du interagiert hast</string>
|
||||
<string name="relationship_severance_account_suspension">Ein Admin von %1$s hat %2$s gesperrt. Du wirst von diesem Profil keine Updates mehr erhalten und auch nicht mit ihm interagieren können.</string>
|
||||
<!-- %1$s is your server domain, %2$s is the domain that was blocked, %3$,d is the follower count, %4$s is the `x_accounts` plural string -->
|
||||
<string name="relationship_severance_domain_block">Ein Admin von %1$s hat %2$s blockiert – darunter %3$,d deiner Follower und %4$s Konten, denen du folgst.</string>
|
||||
<plurals name="x_accounts">
|
||||
<item quantity="one">%,d Konto</item>
|
||||
<item quantity="other">%,d Konten</item>
|
||||
</plurals>
|
||||
<!-- %1$s is the domain that was blocked, %2$,d is the follower count, %3$s is the `x_accounts` plural string -->
|
||||
<string name="relationship_severance_user_domain_block">Du hast %1$s blockiert. %2$,d deiner Follower und %3$s Konten, denen du folgst, wurden entfernt.</string>
|
||||
<string name="relationship_severance_learn_more">Mehr erfahren</string>
|
||||
<string name="moderation_warning_action_none">Dein Konto ist von den Moderator*innen verwarnt worden.</string>
|
||||
<string name="moderation_warning_action_disable">Dein Konto wurde eingeschränkt.</string>
|
||||
<string name="moderation_warning_action_mark_statuses_as_sensitive">Einige deiner Beiträge wurden mit einer Inhaltswarnung versehen.</string>
|
||||
<string name="moderation_warning_action_delete_statuses">Einige deiner Beiträge sind entfernt worden.</string>
|
||||
<string name="moderation_warning_action_sensitive">Deine zukünftigen Beiträge werden mit einer Inhaltswarnung versehen.</string>
|
||||
<string name="moderation_warning_action_silence">Dein Konto wurde eingeschränkt.</string>
|
||||
<string name="moderation_warning_action_suspend">Dein Konto wurde gesperrt.</string>
|
||||
<string name="moderation_warning_learn_more">Mehr erfahren</string>
|
||||
</resources>
|
||||
|
||||
@@ -774,8 +774,14 @@ Zenbat eta jende gehiago jarraitu, orduan eta aktiboagoa eta interesgarriagoa iz
|
||||
<item quantity="one">Erantsitako fitxategi %d</item>
|
||||
<item quantity="other">%d erantsitako fitxategi</item>
|
||||
</plurals>
|
||||
<plurals name="poll_ended_x_voters">
|
||||
<item quantity="one">%1$s erabiltzaileak inkesta bat egin zuen eta zuk eta beste erabiltzaile %2$,d bozkatu duzue</item>
|
||||
<item quantity="other">%1$s erabiltzaileak inkesta bat egin zuen eta zuk eta beste %2$,d erabiltzailek bozkatu duzue</item>
|
||||
</plurals>
|
||||
<string name="own_poll_ended">Zure inkesta amaitu da</string>
|
||||
<string name="user_just_posted">%s erabiltzaileak bidalketa egin berri du</string>
|
||||
<string name="user_edited_post">%s(e)k interaktuatu zenuen argitalpen bat editatu du</string>
|
||||
<string name="relationship_severance_account_suspension">%1$s zerbitzariko administratzaile batek %2$s bertan behera utzi du, hau da, ezin izango dituzu jaso hango eguneratzerik edo hangoekin elkarreragin.</string>
|
||||
<!-- %1$s is your server domain, %2$s is the domain that was blocked, %3$,d is the follower count, %4$s is the `x_accounts` plural string -->
|
||||
<plurals name="x_accounts">
|
||||
<item quantity="one">kontu %,d</item>
|
||||
@@ -789,5 +795,6 @@ Zenbat eta jende gehiago jarraitu, orduan eta aktiboagoa eta interesgarriagoa iz
|
||||
<string name="moderation_warning_action_delete_statuses">Zure argitalpen batzuk kendu dira.</string>
|
||||
<string name="moderation_warning_action_sensitive">Zure bidalketak hunkigarri gisa markatuko dira aurrerantzean.</string>
|
||||
<string name="moderation_warning_action_silence">Zure kontuari mugak jarri zaizkio.</string>
|
||||
<string name="moderation_warning_action_suspend">Zure kontua behin-behinean egotzi da.</string>
|
||||
<string name="moderation_warning_learn_more">Informazio gehiago</string>
|
||||
</resources>
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<string name="notifications">Meldingen</string>
|
||||
<string name="user_followed_you">%s folget jo no</string>
|
||||
<string name="user_sent_follow_request">%s wol jo graach folgje</string>
|
||||
<string name="user_favorited">%s markearre as favoryt:</string>
|
||||
<string name="notification_boosted">%s boostte:</string>
|
||||
<string name="share_toot_title">Diele</string>
|
||||
<string name="settings">Ynstellingen</string>
|
||||
<string name="publish">Publisearje</string>
|
||||
@@ -382,6 +384,12 @@
|
||||
<string name="alt_text">Alternative tekst</string>
|
||||
<string name="help">Help</string>
|
||||
<string name="what_is_alt_text">Wat is alternative tekst?</string>
|
||||
<string name="alt_text_help">Alt-tekst biedt ôfbyldingsbeskriuwingen foar minsken mei in fisuele beheining en ferbiningen mei in lege bânbreedte of foar minsken dy’t nei ekstra kontekst sykje.\n\nJo kinne de tagonklikheid en de begryplikheid foar elkenien ferbetterje troch dúdlik, koart en objektyf te skriuwen.\n\n<ul><li>Beskriuw wichtige eleminten</li>\n<li>Fetsje tekst yn ôfbyldingen gear</li>\n<li>Brûk in normale sinsbou</li>\n<li>Mij oertallige ynformaasje</li>\n<li>Fokusje op trends en wichtige befiningen yn komplekse bylden (lykas diagrammen of kaarten)</li></ul> \n</string>
|
||||
<string name="edit_post">Berjocht bewurkje</string>
|
||||
<string name="no_verified_link">Gjin ferifiearre keppeling</string>
|
||||
<string name="compose_autocomplete_emoji_empty">Emoji trochsykje</string>
|
||||
<string name="compose_autocomplete_users_empty">Fyn wa’t jo sykje</string>
|
||||
<string name="no_search_results">Dizze syktermen leverje gjin resultaat op</string>
|
||||
<string name="language">Taal</string>
|
||||
<string name="language_default">Standert</string>
|
||||
<string name="language_system">Systeem</string>
|
||||
@@ -391,21 +399,78 @@
|
||||
<string name="media_hidden">Media ferstoppe</string>
|
||||
<string name="post_hidden">Berjocht ferstoppe</string>
|
||||
<string name="report_title_post">Berjocht rapportearje</string>
|
||||
<string name="forward_report_explanation">De account stiet op in oare server. Wolle jo dêr ek in anonimisearre kopy fan dit rapport nei ta stjoere?</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="forward_report_to_server">Nei %s trochstjoere</string>
|
||||
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->
|
||||
<string name="reported">Rapportearre</string>
|
||||
<string name="report_unfollow_explanation">As jo harren berjochten net mear op jo starttiidline sjen wolle, moatte jo dizze persoan net mear folgje.</string>
|
||||
<string name="muted_user">%s negearje</string>
|
||||
<string name="report_sent_already_blocked">Jo hawwe dizze brûker al blokkearre, dus jo hoege neat mear te dwaan wylst wy jo rapport beoardiele.</string>
|
||||
<string name="report_personal_already_blocked">Jo hawwe dizze brûker al blokkearre, dus der is neat oars dat jo hoege te dwaan.\n\nTank foar jo help om Mastodon foar elkenien feilich te hâlden!</string>
|
||||
<string name="blocked_user">%s blokkearre</string>
|
||||
<string name="mark_all_notifications_read">Alles as lêzen markearje</string>
|
||||
<string name="settings_display">Werjefte</string>
|
||||
<string name="settings_filters">Filters</string>
|
||||
<string name="settings_server_explanation">Oersjoch, rigels, moderators</string>
|
||||
<!-- %s is the app name (Mastodon, key app_name). I made it a placeholder so everything Just Works™ with forks -->
|
||||
<string name="about_app">Oer %s</string>
|
||||
<string name="default_post_language">Standert taal foar berjochten</string>
|
||||
<string name="settings_alt_text_reminders">Alt-tekst-omtinken tafoegje</string>
|
||||
<string name="settings_confirm_unfollow">Eardat jo ien ûntfolgje om befêstiging freegje</string>
|
||||
<string name="settings_confirm_boost">Eardat jo in berjocht booste om befêstiging freegje</string>
|
||||
<string name="settings_confirm_delete_post">Eardat jo in berjocht fuortsmite om befêstiging freegje</string>
|
||||
<string name="pause_all_notifications">Alles pauzearje</string>
|
||||
<string name="pause_notifications_off">Ut</string>
|
||||
<string name="notifications_policy_anyone">Elkenien</string>
|
||||
<string name="notifications_policy_followed">Minsken dy’t jo folgje</string>
|
||||
<string name="notifications_policy_follower">Minsken dy’t josels folgje</string>
|
||||
<string name="notifications_policy_no_one">Net ien</string>
|
||||
<string name="settings_notifications_policy">Meldingen ûntfange fan</string>
|
||||
<string name="notification_type_mentions_and_replies">Fermeldingen en reaksjes</string>
|
||||
<string name="pause_all_notifications_title">Alle meldingen pauzearje</string>
|
||||
<plurals name="x_weeks">
|
||||
<item quantity="one">%d wike</item>
|
||||
<item quantity="other">%d wiken</item>
|
||||
</plurals>
|
||||
<!-- %1$s is the date (may be relative, e.g. "today" or "yesterday"), %2$s is the time. You can reorder these placeholders if that works better for your language -->
|
||||
<string name="date_at_time">%1$s om %2$s</string>
|
||||
<string name="today">hjoed</string>
|
||||
<string name="yesterday">juster</string>
|
||||
<string name="tomorrow">moarn</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_ends">Einiget om %s</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_banner">Meldingen wurde om %s ferfette.</string>
|
||||
<string name="resume_notifications_now">No ferfetsje</string>
|
||||
<string name="open_system_notification_settings">Gean nei meldingsynstellingen</string>
|
||||
<string name="about_server">Oer</string>
|
||||
<string name="server_rules">Regels</string>
|
||||
<string name="server_administrator">Behearder</string>
|
||||
<string name="send_email_to_server_admin">Berjocht oan behearder</string>
|
||||
<string name="notifications_disabled_in_system">Meldingen yn jo apparaatynstellingen ynskeakelje om oeral fernijingen sjen te kinnen.</string>
|
||||
<string name="settings_even_more">Noch mear ynstellingen</string>
|
||||
<string name="settings_show_cws">Ynhâldswarskôgingen toane</string>
|
||||
<string name="settings_hide_sensitive_media">As gefoelich markearre media ferstopje</string>
|
||||
<string name="settings_show_interaction_counts">Oantal berjochtynteraksjes</string>
|
||||
<string name="settings_show_emoji_in_names">Oanpaste emoji yn werjeftenammen</string>
|
||||
<plurals name="in_x_seconds">
|
||||
<item quantity="one">yn %d sekonde</item>
|
||||
<item quantity="other">yn %d sekonden</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_minutes">
|
||||
<item quantity="one">yn %d minút</item>
|
||||
<item quantity="other">yn %d minuten</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_hours">
|
||||
<item quantity="one">yn %d oere</item>
|
||||
<item quantity="other">yn %d oeren</item>
|
||||
</plurals>
|
||||
<plurals name="x_hours_ago">
|
||||
<item quantity="one">%d oere lyn</item>
|
||||
<item quantity="other">%d oeren lyn</item>
|
||||
</plurals>
|
||||
<string name="alt_text_reminder_title">Media sûnder alt-tekst</string>
|
||||
<string name="count_one">Ien</string>
|
||||
<string name="count_two">Twa</string>
|
||||
<string name="count_three">Trije</string>
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<string name="notifications">Notifikasi</string>
|
||||
<string name="user_followed_you">%s mengikuti Anda</string>
|
||||
<string name="user_sent_follow_request">%s mengirim Anda permintaan pengikut</string>
|
||||
<string name="user_favorited">%s memfavorit:</string>
|
||||
<string name="notification_boosted">%s membagikan ulang:</string>
|
||||
<string name="share_toot_title">Bagikan</string>
|
||||
<string name="settings">Pengaturan</string>
|
||||
<string name="publish">Terbitkan</string>
|
||||
@@ -730,6 +732,39 @@
|
||||
<string name="donation_server_error">Maafkan kami, kesalahan telah terjadi dan kami belum bisa memproses donasi anda.\n\nMohon ulang kembali beberapa menit lagi.</string>
|
||||
<string name="settings_donate">Donasi ke Mastodon</string>
|
||||
<string name="settings_manage_donations">Kelola donasi</string>
|
||||
<string name="cant_load_image">Tidak dapat memuat gambar</string>
|
||||
<string name="poll_see_results">Lihat hasil</string>
|
||||
<string name="poll_hide_results">Sembunyikan hasil</string>
|
||||
<plurals name="x_attachments">
|
||||
<item quantity="other">%d lampiran</item>
|
||||
</plurals>
|
||||
<plurals name="user_and_x_more_favorited">
|
||||
<item quantity="other">%1$s dan %2$,d lainnya memfavorit:</item>
|
||||
</plurals>
|
||||
<plurals name="user_and_x_more_boosted">
|
||||
<item quantity="other">%1$s dan %2$,d lainnya membagikan ulang:</item>
|
||||
</plurals>
|
||||
<plurals name="poll_ended_x_voters">
|
||||
<item quantity="other">%1$s memulai japat yang Anda dan %2$,d lainnya beri suara</item>
|
||||
</plurals>
|
||||
<string name="own_poll_ended">Japat Anda telah berakhir</string>
|
||||
<string name="user_just_posted">%s baru saja mengirim</string>
|
||||
<string name="user_edited_post">%s menyunting kiriman yang Anda interaksi</string>
|
||||
<string name="relationship_severance_account_suspension">Seorang admin dari %1$s telah menangguhkan %2$s, yang berarti Anda tidak dapat lagi menerima pembaruan atau berinteraksi.</string>
|
||||
<!-- %1$s is your server domain, %2$s is the domain that was blocked, %3$,d is the follower count, %4$s is the `x_accounts` plural string -->
|
||||
<string name="relationship_severance_domain_block">Seorang admin dari %1$s telah memblokir %2$s, termasuk %3$,d dari pengikut Anda dan %4$s lain yang Anda ikuti.</string>
|
||||
<plurals name="x_accounts">
|
||||
<item quantity="other">%,d akun</item>
|
||||
</plurals>
|
||||
<!-- %1$s is the domain that was blocked, %2$,d is the follower count, %3$s is the `x_accounts` plural string -->
|
||||
<string name="relationship_severance_user_domain_block">Anda telah memblokir %1$s, menghapus %2$,d dari pengikut Anda dan %3$s lain yang Anda ikuti.</string>
|
||||
<string name="relationship_severance_learn_more">Pelajari lebih lanjut</string>
|
||||
<string name="moderation_warning_action_none">Akun Anda telah menerima peringatan moderasi.</string>
|
||||
<string name="moderation_warning_action_disable">Akun Anda telah dinonaktifkan.</string>
|
||||
<string name="moderation_warning_action_mark_statuses_as_sensitive">Beberapa kiriman Anda telah ditandai sebagai sensitif.</string>
|
||||
<string name="moderation_warning_action_delete_statuses">Beberapa kiriman Anda telah dihapus.</string>
|
||||
<string name="moderation_warning_action_sensitive">Kiriman Anda akan ditandai sebagai sensitif mulai dari sekarang.</string>
|
||||
<string name="moderation_warning_action_silence">Akun Anda telah dibatasi.</string>
|
||||
<string name="moderation_warning_action_suspend">Akun Anda telah ditangguhkan.</string>
|
||||
<string name="moderation_warning_learn_more">Pelajari lebih lanjut</string>
|
||||
</resources>
|
||||
|
||||
@@ -725,7 +725,7 @@
|
||||
<string name="notification_filter_new_accounts">Nieuwe accounts</string>
|
||||
<string name="notification_filter_new_accounts_explanation">In de afgelopen 30 dagen geregistreerd</string>
|
||||
<string name="notification_filter_mentions">Ongevraagde privéberichten</string>
|
||||
<string name="notification_filter_mentions_explanation">Onzichtbaar tenzij het een antwoord is op een privébericht van jou of wanneer je de afzender volgt</string>
|
||||
<string name="notification_filter_mentions_explanation">Onzichtbaar tenzij het een reactie is op een privébericht van jou of wanneer je de afzender volgt</string>
|
||||
<string name="allow_notifications">Meldingen toestaan</string>
|
||||
<string name="mute_notifications">Meldingen afwijzen</string>
|
||||
<plurals name="x_people_you_may_know">
|
||||
@@ -786,8 +786,24 @@
|
||||
<item quantity="other">%1$s hield een peiling, waaraan jij en %2$,d andere personen hebben meegedaan</item>
|
||||
</plurals>
|
||||
<string name="own_poll_ended">Jouw peiling is beëindigd</string>
|
||||
<string name="user_just_posted">%s heeft zojuist een bericht geplaatst</string>
|
||||
<string name="user_edited_post">%s bewerkte een bericht waarmee je interactie had</string>
|
||||
<string name="relationship_severance_account_suspension">Een beheerder van %1$s heeft %2$s geschorst, wat betekent dat je geen updates meer van hen kunt ontvangen of met hen kunt communiceren.</string>
|
||||
<!-- %1$s is your server domain, %2$s is the domain that was blocked, %3$,d is the follower count, %4$s is the `x_accounts` plural string -->
|
||||
<string name="relationship_severance_domain_block">Een beheerder van %1$s heeft %2$s geblokkeerd, inclusief %3$,d van jouw volgers en %4$s account(s) die je volgt.</string>
|
||||
<plurals name="x_accounts">
|
||||
<item quantity="one">%,d account</item>
|
||||
<item quantity="other">%,d accounts</item>
|
||||
</plurals>
|
||||
<!-- %1$s is the domain that was blocked, %2$,d is the follower count, %3$s is the `x_accounts` plural string -->
|
||||
<string name="relationship_severance_user_domain_block">Je hebt %1$s geblokkeerd, waarmee je %2$,d van je volgers en %3$s account(s) die je volgt, bent verloren.</string>
|
||||
<string name="relationship_severance_learn_more">Meer informatie</string>
|
||||
<string name="moderation_warning_action_none">Jouw account heeft een moderatie-waarschuwing ontvangen.</string>
|
||||
<string name="moderation_warning_action_disable">Jouw account is uitgeschakeld.</string>
|
||||
<string name="moderation_warning_action_mark_statuses_as_sensitive">Sommige van je berichten zijn gemarkeerd als gevoelig.</string>
|
||||
<string name="moderation_warning_action_delete_statuses">Sommige van je berichten zijn verwijderd.</string>
|
||||
<string name="moderation_warning_action_sensitive">Je berichten worden vanaf nu als gevoelig gemarkeerd.</string>
|
||||
<string name="moderation_warning_action_silence">Jouw account is beperkt.</string>
|
||||
<string name="moderation_warning_action_suspend">Jouw account is opgeschort.</string>
|
||||
<string name="moderation_warning_learn_more">Meer informatie</string>
|
||||
</resources>
|
||||
|
||||
@@ -464,7 +464,7 @@
|
||||
<string name="notifications_policy_no_one">Никого</string>
|
||||
<string name="settings_notifications_policy">Получать уведомления от</string>
|
||||
<string name="notification_type_mentions_and_replies">Упоминания и ответы</string>
|
||||
<string name="pause_all_notifications_title">Просмотреть все уведомления</string>
|
||||
<string name="pause_all_notifications_title">Приостановить все уведомления</string>
|
||||
<plurals name="x_weeks">
|
||||
<item quantity="one">%d неделя</item>
|
||||
<item quantity="few">%d недели</item>
|
||||
|
||||
@@ -45,4 +45,11 @@
|
||||
<color name="m3_sys_dark_on_surface_variant">@android:color/system_neutral2_200</color>
|
||||
<color name="m3_sys_dark_outline">@android:color/system_neutral2_400</color>
|
||||
<color name="m3_sys_dark_outline_variant">@android:color/system_neutral2_700</color>
|
||||
|
||||
<color name="ext_rich_text_text_light">@android:color/system_accent3_700</color>
|
||||
<color name="ext_rich_text_container_light">@android:color/system_accent3_100</color>
|
||||
<color name="ext_rich_text_decoration_light">@android:color/system_accent3_200</color>
|
||||
<color name="ext_rich_text_text_dark">@android:color/system_accent3_200</color>
|
||||
<color name="ext_rich_text_container_dark">@android:color/system_accent3_800</color>
|
||||
<color name="ext_rich_text_decoration_dark">#0f0</color> <!-- it's "tertiary 35" but oh well -->
|
||||
</resources>
|
||||
|
||||
@@ -276,7 +276,7 @@
|
||||
<string name="file_size_gb">%.2f GB</string>
|
||||
<string name="upload_processing">正在处理…</string>
|
||||
<!-- %s is file size -->
|
||||
<string name="download_update">已下载(%s)</string>
|
||||
<string name="download_update">下载(%s)</string>
|
||||
<string name="install_update">安装</string>
|
||||
<string name="privacy_policy_title">你的隐私</string>
|
||||
<string name="privacy_policy_subtitle">尽管 Mastodon 客户端本身不采集任何数据,你注册的实例可能会有不同的隐私政策。\n\n如果你不同意 %s 的这些政策,请返回并选择其他实例。</string>
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
<attr name="colorWhite" format="color"/>
|
||||
<attr name="colorFavorite" format="color" />
|
||||
<attr name="colorBoost" format="color" />
|
||||
<attr name="colorRichTextText" format="color"/>
|
||||
<attr name="colorRichTextContainer" format="color"/>
|
||||
<attr name="colorRichTextDecorations" format="color"/>
|
||||
|
||||
<declare-styleable name="MaxWidthFrameLayout">
|
||||
<attr name="android:maxWidth" format="dimension"/>
|
||||
|
||||
@@ -104,5 +104,12 @@
|
||||
<color name="ext_on_bookmark_container_light_medium_contrast">#FFFFFF</color>
|
||||
<color name="ext_on_bookmark_container_dark">#FFFFFF</color>
|
||||
|
||||
<color name="ext_rich_text_text_light">#6C3646</color>
|
||||
<color name="ext_rich_text_container_light">#FFD9E1</color>
|
||||
<color name="ext_rich_text_decoration_light">#FDB2C5</color>
|
||||
<color name="ext_rich_text_text_dark">#FDB2C5</color>
|
||||
<color name="ext_rich_text_container_dark">#512030</color>
|
||||
<color name="ext_rich_text_decoration_dark">#7A4152</color>
|
||||
|
||||
<item name="overlay_ripple_alpha" format="float" type="dimen">0.12</item>
|
||||
</resources>
|
||||
@@ -58,6 +58,9 @@
|
||||
<item name="colorWhite">#FFF</item>
|
||||
<item name="colorFavorite">@color/ext_favorite_light</item>
|
||||
<item name="colorBoost">@color/ext_boost_light</item>
|
||||
<item name="colorRichTextText">@color/ext_rich_text_text_light</item>
|
||||
<item name="colorRichTextContainer">@color/ext_rich_text_container_light</item>
|
||||
<item name="colorRichTextDecorations">@color/ext_rich_text_decoration_light</item>
|
||||
|
||||
<item name="android:statusBarColor">?colorM3Background</item>
|
||||
<item name="android:navigationBarColor">@color/navigation_bar_bg_light</item>
|
||||
@@ -126,6 +129,9 @@
|
||||
<item name="colorWhite">#000</item>
|
||||
<item name="colorFavorite">@color/ext_favorite_dark</item>
|
||||
<item name="colorBoost">@color/ext_boost_dark</item>
|
||||
<item name="colorRichTextText">@color/ext_rich_text_text_dark</item>
|
||||
<item name="colorRichTextContainer">@color/ext_rich_text_container_dark</item>
|
||||
<item name="colorRichTextDecorations">@color/ext_rich_text_decoration_dark</item>
|
||||
|
||||
<item name="android:statusBarColor">?colorM3Background</item>
|
||||
<item name="android:navigationBarColor">?colorM3Background</item>
|
||||
|
||||
Reference in New Issue
Block a user