Merge remote-tracking branch 'megalodon_main/main'

# Conflicts:
#	mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java
#	mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposePollViewController.java
#	metadata/uk/changelogs/56.txt
This commit is contained in:
LucasGGamerM 2023-10-25 20:10:41 -03:00
commit 828d07d6b5
21 changed files with 273 additions and 83 deletions

View File

@ -551,10 +551,14 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
protected void updatePoll(String itemID, Status status, Poll poll){
status.poll=poll;
int firstOptionIndex=-1, footerIndex=-1;
int spoilerFirstOptionIndex=-1, spoilerFooterIndex=-1;
SpoilerStatusDisplayItem spoilerItem=null;
int i=0;
for(StatusDisplayItem item:displayItems){
if(item.parentID.equals(itemID)){
if(item instanceof PollOptionStatusDisplayItem && firstOptionIndex==-1){
if(item instanceof SpoilerStatusDisplayItem){
spoilerItem=(SpoilerStatusDisplayItem) item;
}else if(item instanceof PollOptionStatusDisplayItem && firstOptionIndex==-1){
firstOptionIndex=i;
}else if(item instanceof PollFooterStatusDisplayItem){
footerIndex=i;
@ -567,8 +571,16 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
throw new IllegalStateException("Can't find all poll items in displayItems");
List<StatusDisplayItem> pollItems=displayItems.subList(firstOptionIndex, footerIndex+1);
int prevSize=pollItems.size();
if(spoilerItem!=null){
spoilerFirstOptionIndex=spoilerItem.contentItems.indexOf(pollItems.get(0));
spoilerFooterIndex=spoilerItem.contentItems.indexOf(pollItems.get(pollItems.size()-1));
}
pollItems.clear();
StatusDisplayItem.buildPollItems(itemID, this, poll, pollItems, status);
if(spoilerItem!=null){
spoilerItem.contentItems.subList(spoilerFirstOptionIndex, spoilerFooterIndex+1).clear();
spoilerItem.contentItems.addAll(spoilerFirstOptionIndex, pollItems);
}
if(prevSize!=pollItems.size()){
adapter.notifyItemRangeRemoved(firstOptionIndex, prevSize);
adapter.notifyItemRangeInserted(firstOptionIndex, pollItems.size());

View File

@ -215,7 +215,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
public Instance instance;
public Status editingStatus;
private ScheduledStatus scheduledStatus;
public ScheduledStatus scheduledStatus;
private boolean redraftStatus;
private Uri photoUri;
@ -758,7 +758,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(16)));
}
replyText.setText(getString(quote!=null? R.string.sk_quoting_user : R.string.in_reply_to, status.account.getDisplayName()));
replyText.setText(HtmlParser.parseCustomEmoji(getString(quote!=null? R.string.sk_quoting_user : R.string.in_reply_to, status.account.getDisplayName()), status.account.emojis));
UiUtils.loadCustomEmojiInTextView(replyText);
int visibilityNameRes = switch (status.visibility) {
case PUBLIC -> R.string.visibility_public;
case UNLISTED -> R.string.sk_visibility_unlisted;

View File

@ -8,10 +8,14 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusUpdatedEvent;
import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.Status;
@ -23,9 +27,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import me.grishka.appkit.api.Callback;
@ -51,6 +57,7 @@ public class HomeTimelineFragment extends StatusListFragment {
@Override
protected void doLoadData(int offset, int count){
String maxID=this.maxID;
AccountSessionManager.getInstance()
.getAccount(accountID).getCacheController()
.getHomeTimeline(offset>0 ? maxID : null, count, refreshing, new SimpleCallback<>(this){
@ -58,7 +65,8 @@ public class HomeTimelineFragment extends StatusListFragment {
public void onSuccess(CacheablePaginatedResponse<List<Status>> result){
if(getActivity()==null) return;
boolean empty=result.items.isEmpty();
maxID=result.maxID;
if(result.isFromCache()) refreshCachedData(result, maxID);
HomeTimelineFragment.this.maxID=result.maxID;
AccountSessionManager.get(accountID).filterStatuses(result.items, getFilterContext());
onDataLoaded(result.items, !empty);
if(result.isFromCache() && GlobalUserPreferences.loadNewPosts)
@ -67,6 +75,53 @@ public class HomeTimelineFragment extends StatusListFragment {
});
}
private void handleRefreshedData(List<Status> result, List<Status> cachedList){
Map<String, Status> refreshed=result.stream().collect(Collectors.toMap(Status::getID, Function.identity()));
for(Status cached : cachedList){
if(refreshed.containsKey(cached.id)){
Status updated=refreshed.get(cached.id);
if(updated.editedAt!=null && cached.editedAt!=null && updated.editedAt.isAfter(cached.editedAt))
E.post(new StatusUpdatedEvent(updated));
else
E.post(new StatusCountersUpdatedEvent(updated.getContentStatus()));
}else{
removeStatus(cached);
}
}
}
private void refreshCachedData(CacheablePaginatedResponse<List<Status>> result, String maxID){
List<Status> cachedList=new ArrayList<>(result.items);
if(cachedList.isEmpty()) return;
if(maxID==null){
// fetch top status manually so we can use its id as the max_id to fetch the rest
Status firstFromCache=cachedList.get(0);
maxID=firstFromCache.id;
cachedList.remove(0);
new GetStatusByID(maxID).setCallback(new Callback<>(){
@Override
public void onSuccess(Status result){
handleRefreshedData(
Collections.singletonList(result),
Collections.singletonList(firstFromCache)
);
}
@Override
public void onError(ErrorResponse ignored){}
}).exec(accountID);
}
new GetHomeTimeline(maxID, null, cachedList.size(), null, getSession().getLocalPreferences().timelineReplyVisibility).setCallback(new Callback<>(){
@Override
public void onSuccess(List<Status> result){
handleRefreshedData(result, cachedList);
}
@Override
public void onError(ErrorResponse ignored){}
}).exec(accountID);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);

View File

@ -6,6 +6,7 @@ import org.joinmastodon.android.model.Poll.Option;
import org.parceler.Parcel;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
@ -27,10 +28,10 @@ public class ScheduledStatus extends BaseModel implements DisplayItemsParent{
@Override
public void postprocess() throws ObjectValidationException {
super.postprocess();
if (mediaAttachments == null) mediaAttachments = List.of();
if(mediaAttachments==null) mediaAttachments=List.of();
for(Attachment a:mediaAttachments)
a.postprocess();
if (params != null) params.postprocess();
if(params!=null) params.postprocess();
}
@Parcel
@ -53,7 +54,7 @@ public class ScheduledStatus extends BaseModel implements DisplayItemsParent{
@Override
public void postprocess() throws ObjectValidationException {
super.postprocess();
if (poll != null) poll.postprocess();
if(poll!=null) poll.postprocess();
}
}
@ -67,25 +68,26 @@ public class ScheduledStatus extends BaseModel implements DisplayItemsParent{
public boolean hideTotals;
public Poll toPoll() {
Poll p = new Poll();
p.voted = true;
p.emojis = List.of();
p.ownVotes = List.of();
p.multiple = multiple;
p.options = options.stream().map(Option::new).collect(Collectors.toList());
Poll p=new Poll();
p.voted=true;
p.emojis=List.of();
p.ownVotes=List.of();
p.multiple=multiple;
p.options=options.stream().map(Option::new).collect(Collectors.toList());
p.expiresAt=Instant.now().plus(Integer.parseInt(expiresIn)+1, ChronoUnit.SECONDS);
return p;
}
}
public Status toStatus() {
Status s = Status.ofFake(id, params.text, scheduledAt);
s.mediaAttachments = mediaAttachments;
s.inReplyToId = params.inReplyToId > 0 ? "" + params.inReplyToId : null;
s.spoilerText = params.spoilerText;
s.visibility = params.visibility;
s.language = params.language;
s.sensitive = params.sensitive;
if (params.poll != null) s.poll = params.poll.toPoll();
Status s=Status.ofFake(id, params.text, scheduledAt);
s.mediaAttachments=mediaAttachments;
s.inReplyToId=params.inReplyToId>0 ? ""+params.inReplyToId : null;
s.spoilerText=params.spoilerText;
s.visibility=params.visibility;
s.language=params.language;
s.sensitive=params.sensitive;
if(params.poll!=null) s.poll=params.poll.toPoll();
return s;
}
}

View File

@ -566,7 +566,8 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
follow.setIcon(following ? R.drawable.ic_fluent_person_delete_24_regular : R.drawable.ic_fluent_person_add_24_regular);
manageUserLists.setVisible(relationship != null && relationship.following);
manageUserLists.setTitle(item.parentFragment.getString(R.string.sk_lists_with_user, username));
UiUtils.insetPopupMenuIcon(item.parentFragment.getContext(), follow);
// ic_fluent_person_add_24_regular actually has a width of 25dp -.-
UiUtils.insetPopupMenuIcon(item.parentFragment.getContext(), follow, following ? 0 : V.dp(-1));
}
workaroundChangingMenuItemWidths(menu, username);

View File

@ -6,6 +6,7 @@ import static org.joinmastodon.android.ui.utils.UiUtils.generateFormattedString;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.ColorStateList;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
@ -143,6 +144,8 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{
item.emojiHelper.setImageDrawable(index-1, image);
text.invalidate();
}
if(image instanceof Animatable)
((Animatable) image).start();
}
@Override

View File

@ -814,8 +814,8 @@ public class UiUtils {
button.setText(relationship.followedBy ? R.string.follow_back : R.string.button_follow);
styleRes=R.style.Widget_Mastodon_M3_Button_Filled;
}else{
button.setText(R.string.button_following);
styleRes=R.style.Widget_Mastodon_M3_Button_Tonal;
button.setText(relationship.followedBy ? R.string.sk_button_mutuals : R.string.button_following);
styleRes=relationship.followedBy ? R.style.Widget_Mastodon_M3_Button_Tonal_Outlined : R.style.Widget_Mastodon_M3_Button_Tonal;
}
TypedArray ta=button.getContext().obtainStyledAttributes(styleRes, new int[]{android.R.attr.background});
@ -941,17 +941,26 @@ public class UiUtils {
}
public static void insetPopupMenuIcon(Context context, MenuItem item) {
ColorStateList iconTint = ColorStateList.valueOf(UiUtils.getThemeColor(context, android.R.attr.textColorSecondary));
insetPopupMenuIcon(item, iconTint);
insetPopupMenuIcon(context, item, 0);
}
public static void insetPopupMenuIcon(MenuItem item, ColorStateList iconTint) {
Drawable icon = item.getIcon().mutate();
if (Build.VERSION.SDK_INT >= 26) item.setIconTintList(iconTint);
public static void insetPopupMenuIcon(Context context, MenuItem item, int addWidth) {
ColorStateList iconTint = ColorStateList.valueOf(UiUtils.getThemeColor(context, android.R.attr.textColorSecondary));
insetPopupMenuIcon(item, iconTint, addWidth);
}
/**
* @param addWidth set if icon is too wide/narrow. if icon is 25dp in width, set to -1dp
*/
public static void insetPopupMenuIcon(MenuItem item, ColorStateList iconTint, int addWidth) {
Drawable icon=item.getIcon().mutate();
if(Build.VERSION.SDK_INT>=26) item.setIconTintList(iconTint);
else icon.setTintList(iconTint);
icon = new InsetDrawable(icon, V.dp(8), 0, V.dp(8), 0);
int pad=V.dp(8);
boolean rtl=icon.getLayoutDirection()==View.LAYOUT_DIRECTION_RTL;
icon=new InsetDrawable(icon, rtl ? pad+addWidth : pad, 0, rtl ? pad : addWidth+pad, 0);
item.setIcon(icon);
SpannableStringBuilder ssb = new SpannableStringBuilder(item.getTitle());
SpannableStringBuilder ssb = new SpannableStringBuilder(item.getTitle());
item.setTitle(ssb);
}
@ -985,7 +994,7 @@ public class UiUtils {
if (subMenu != null) enableMenuIcons(context, subMenu, exclude);
if (item.getIcon() == null || Arrays.stream(exclude).anyMatch(id -> id == item.getItemId()))
continue;
insetPopupMenuIcon(item, iconTint);
insetPopupMenuIcon(item, iconTint, 0);
}
}

View File

@ -134,7 +134,9 @@ public class ComposePollViewController{
DraftPollOption opt=createDraftPollOption(false);
opt.edit.setText(eopt.title);
}
if(fragment.editingStatus.poll.expiresAt!=null)
if(fragment.scheduledStatus!=null && fragment.scheduledStatus.params.poll!=null)
pollDuration=Integer.parseInt(fragment.scheduledStatus.params.poll.expiresIn);
else if(fragment.editingStatus.poll.expiresAt!=null)
pollDuration=(int)fragment.editingStatus.poll.expiresAt.minus(fragment.editingStatus.createdAt.toEpochMilli(), ChronoUnit.MILLIS).getEpochSecond();
updatePollOptionHints();
pollDurationValue.setText(UiUtils.formatDuration(fragment.getContext(), pollDuration));

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/m3_primary_overlay">
<item android:gravity="center_vertical" android:height="40dp">
<selector>
<item android:state_enabled="true">
<shape>
<solid android:color="?colorM3SecondaryContainer"/>
<stroke android:color="?colorM3OnSecondaryContainer" android:width="1dp"/>
<corners android:radius="20dp"/>
</shape>
</item>
<item>
<shape>
<solid android:color="?colorM3DisabledBackground"/>
<corners android:radius="20dp"/>
</shape>
</item>
</selector>
</item>
<item android:id="@android:id/mask" android:gravity="center_vertical" android:height="40dp">
<shape>
<solid android:color="#000"/>
<corners android:radius="20dp"/>
</shape>
</item>
</ripple>

View File

@ -1,3 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="25dp" android:height="24dp" android:viewportWidth="25" android:viewportHeight="24">
<path android:pathData="M12.416 2c5.523 0 10 4.477 10 10s-4.477 10-10 10-10-4.477-10-10 4.477-10 10-10zm6.517 4.543L6.96 18.517c1.477 1.238 3.38 1.983 5.457 1.983 4.694 0 8.5-3.806 8.5-8.5 0-2.077-0.745-3.98-1.983-5.457zM12.416 3.5c-4.694 0-8.5 3.806-8.5 8.5 0 2.077 0.745 3.98 1.983 5.457L17.873 5.483C16.396 4.245 14.493 3.5 12.416 3.5z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@ -262,6 +262,7 @@
<!-- %s is the server domain -->
<string name="local_timeline_info_banner">Dies sind alle Beiträge von allen Benutzern auf deinem Server (%s).</string>
<string name="recommended_accounts_info_banner">Dir könnten diese Konten gefallen, basierend auf Leuten, denen du folgst.</string>
<string name="see_new_posts">Neue Beiträge</string>
<string name="load_missing_posts">Weitere Beiträge laden</string>
<string name="follow_back">Zurückfolgen</string>
<string name="button_follow_pending">Ausstehend</string>
@ -386,7 +387,7 @@
<string name="welcome_to_mastodon">Willkommen auf Mastodon</string>
<string name="welcome_paragraph1">Mastodon ist ein dezentrales, soziales Netzwerk. Das bedeutet, dass es nicht von einem einzigen Unternehmen kontrolliert wird. Das Netzwerk besteht aus unabhängig voneinander betriebenen Servern, die miteinander verbunden sind.</string>
<string name="what_are_servers">Was sind Server?</string>
<string name="welcome_paragraph2"><![CDATA[Jedes Mastodon-Konto wird auf einem Server gehostet. Jeder Server hat dabei seine eigenen Werte, Regeln und Administrator*innen. Aber egal, für welchen Server Du Dich entscheidest: Du kannst mit Leuten von anderen Servern interagieren und ihnen folgen.]]></string>
<string name="welcome_paragraph2">Jedes Mastodon-Konto wird auf einem Server erstellt jeder mit eigenen Werten, Regeln &amp; Administrator*innen. Du kannst trotzdem mit Personen interagieren, die ihr Konto auf einem anderen Server erstellt haben.</string>
<string name="opening_link">Link wird geöffnet…</string>
<string name="link_not_supported">Dieser Link wird in der App nicht unterstützt</string>
<string name="log_out_all_accounts">Von allen Konten abmelden</string>
@ -582,9 +583,49 @@
<string name="time_hours_ago_short">vor %d Stunden</string>
<string name="time_days_ago_short">vor %d Tagen</string>
<!-- %s is the name of the post language -->
<string name="translate_post">Übersetzen aus %s</string>
<!-- %1$s is the language, %2$s is the name of the translation service -->
<string name="post_translated">Übersetzt aus %1$s mit %2$s</string>
<string name="translation_show_original">Original anzeigen</string>
<string name="translation_failed">Übersetzung fehlgeschlagen. Möglicherweise haben die Administrator*innen die Übersetzungen auf diesem Server nicht aktiviert oder dieser Server läuft mit einer älteren Version von Mastodon, in der Übersetzungen noch nicht unterstützt wurden.</string>
<string name="settings_privacy">Datenschutz und Reichweite</string>
<string name="settings_discoverable">Profil und Beiträge in Suchalgorithmen berücksichtigen</string>
<string name="settings_indexable">Öffentliche Beiträge in die Suchergebnisse einbeziehen</string>
<string name="error_playing_video">Fehler bei Videowiedergabe</string>
<string name="timeline_following">Folge ich</string>
<string name="lists">Listen</string>
<string name="followed_hashtags">Gefolgte Hashtags</string>
<string name="no_lists">Du hast noch keine Listen.</string>
<string name="no_followed_hashtags">Du folgst keinen Hashtags.</string>
<string name="manage_lists">Listen verwalten</string>
<string name="manage_hashtags">Hashtags verwalten</string>
<!-- Screen reader description for the menu on the home timeline screen -->
<string name="dropdown_menu">Dropdown-Menü</string>
<string name="edit_list">Liste bearbeiten</string>
<string name="list_members">Mitglieder auflisten</string>
<string name="delete_list">Liste löschen</string>
<!-- %s is the name of the list -->
<string name="delete_list_confirm">„%s“ löschen?</string>
<string name="list_exclusive">Mitglieder in „Folge ich“ ausblenden</string>
<string name="list_exclusive_subtitle">Wenn jemand in dieser Liste ist, sollen deren Beiträge nicht in der „Folge ich“-Timeline angezeigt werden.</string>
<string name="list_name">Listenname</string>
<string name="list_show_replies_to">Mit Antworten von</string>
<string name="list_replies_no_one">Niemandem</string>
<string name="list_replies_members">Mitgliedern der Liste</string>
<string name="list_replies_anyone">Benutzer*innen, denen ich folge</string>
<string name="confirm_remove_list_members">Mitglieder entfernen?</string>
<string name="remove">Entfernen</string>
<string name="add_list_member">Mitglied hinzufügen</string>
<string name="search_among_people_you_follow">Suche nach Leuten, denen du folgst</string>
<string name="add_user_to_list">Zur Liste hinzufügen…</string>
<string name="add_user_to_list_title">Zur Liste hinzufügen</string>
<!-- %s is a username -->
<string name="see_new_posts">Neue Beiträge anzeigen</string>
<string name="manage_user_lists">Listen mit %s verwalten</string>
<string name="remove_from_list">Aus Liste entfernen</string>
<string name="confirm_remove_list_member">Mitglied entfernen?</string>
<string name="no_followed_hashtags_title">Halte Interessen im Blick, indem du Hashtags folgst</string>
<string name="no_followed_hashtags_subtitle">Gefolge Hashtags erscheinen hier</string>
<string name="no_lists_title">Startseite mit Listen organisieren</string>
<string name="no_lists_subtitle">Deine werden hier erscheinen</string>
<string name="manage_accounts">Konten hinzufügen oder wechseln</string>
</resources>

View File

@ -415,4 +415,5 @@
<string name="sk_settings_default_visibility">Standard-Sichtbarkeit für Posts</string>
<string name="sk_settings_lock_account">Neue Follower_innen manuell genehmigen</string>
<string name="sk_timeline_cache_cleared">Start-Timeline geleert</string>
<string name="sk_button_mutuals">Befreundet</string>
</resources>

View File

@ -84,6 +84,10 @@
<item quantity="one">%d egun falta da</item>
<item quantity="other">%d egun falta dira</item>
</plurals>
<plurals name="x_votes">
<item quantity="one">Boto %,d</item>
<item quantity="other">%,d boto</item>
</plurals>
<string name="poll_closed">Itxita</string>
<string name="confirm_mute_title">Mututu kontua</string>
<string name="confirm_mute">Berretsi %s mututzea</string>

View File

@ -256,7 +256,7 @@
<string name="sk_filtered">Filtrados: %s</string>
<string name="sk_expand">Expandir</string>
<string name="sk_settings_collapse_long_posts">Contraer publicacións moi longas</string>
<string name="sk_unfinished_attachments">Arranxar arquivos adxuntos\?</string>
<string name="sk_unfinished_attachments">Subindo arquivos adxuntos</string>
<string name="sk_spectator_mode">Modo espectador</string>
<string name="sk_settings_hide_interaction">Ocultar botóns de interacción</string>
<string name="sk_follow_as">Seguir dende outra conta</string>
@ -330,10 +330,10 @@
<string name="sk_gif_badge">GIF</string>
<string name="sk_settings_unifiedpush_no_distributor_body">Debe instalar un distribuidor para que as notificacións UnifiedPush funcionen. Para máis información, visita https://unifiedpush.org/</string>
<string name="sk_settings_unifiedpush_no_distributor">Non se atopou ningún distribuidor</string>
<string name="sk_trending_posts_info_banner">Estas son publicacións que están a gañar tracción no teu servidor.</string>
<string name="sk_trending_posts_info_banner">Estas publicacións están a gañar tracción no Fediverso.</string>
<string name="sk_settings_unifiedpush_choose">Escoller un distribuidor</string>
<string name="sk_settings_continues_playback">Superposición de audio</string>
<string name="sk_trending_links_info_banner">Estas son as novas historias das que se está a falar no teu servidor.</string>
<string name="sk_trending_links_info_banner">Destas novas historias se está a falar en todo o Fediverso.</string>
<string name="sk_settings_unifiedpush">Empregar UnifiedPush</string>
<string name="sk_disable_pill_shaped_active_indicator">Desactivar o indicador de lapela activa en forma de pílula</string>
<string name="sk_tab_profile">Perfil</string>
@ -373,7 +373,7 @@
<string name="sk_search_suicide_hotlines">Buscar unha liña de axuda</string>
<string name="sk_duration_hours_1">1 hora</string>
<string name="sk_duration_hours_6">6 horas</string>
<string name="sk_enter_emoji_hint">Escribe para reaccionar cunha emoticona</string>
<string name="sk_enter_emoji_hint">Escribe unha emoticona ou busca</string>
<string name="sk_duration_days_7">7 días</string>
<string name="sk_do_not_show_again">Non amosar outra vez</string>
<string name="sk_suicide_helplines_url">https://findahelpline.com/es</string>
@ -396,4 +396,12 @@
<string name="sk_blocked_accounts">Contas bloqueadas</string>
<string name="sk_muted_accounts">Contas silenciadas</string>
<string name="sk_recently_used">Empregados recentemente</string>
<string name="sk_set_as_default">Establecer como predefinido</string>
<string name="sk_settings_color_palette_default">Defecto (%s)</string>
<string name="sk_settings_default_visibility">Visibilidade de publicación por defecto</string>
<string name="sk_settings_underlined_links">Ligazóns subliñadas</string>
<string name="sk_settings_lock_account">Aprobar manualmente novos seguidores</string>
<string name="sk_timeline_cache_cleared">Caché da cronoloxía de inicio borrada</string>
<string name="sk_settings_clear_timeline_cache">Borrar a caché da cronoloxía de inicio</string>
<string name="sk_edit_alt_text">Editar texto alternativo</string>
</resources>

View File

@ -639,4 +639,6 @@
<item quantity="one">%,d nýleg færsla</item>
<item quantity="other">%,d nýlegar færslur</item>
</plurals>
<string name="step_x_of_y">Skref %1$d af %2$d</string>
<string name="create">Búa til</string>
</resources>

View File

@ -608,4 +608,10 @@
<plurals name="x_posts_recently">
<item quantity="other">%,d โพสต์ล่าสุด</item>
</plurals>
<string name="create_list">สร้างรายการ</string>
<string name="step_x_of_y">ขั้นตอนที่ %1$d จาก %2$d</string>
<string name="create">สร้าง</string>
<string name="manage_list_members">จัดการสมาชิกของรายการ</string>
<string name="list_no_members">ยังไม่มีสมาชิก</string>
<string name="list_find_users">ค้นหาผู้ใช้ที่จะเพิ่ม</string>
</resources>

View File

@ -249,6 +249,7 @@
<!-- %s is the server domain -->
<string name="local_timeline_info_banner">Đây là những tút từ người trên máy chủ của bạn (%s)</string>
<string name="recommended_accounts_info_banner">Có thể bạn quen những người này chăng?!</string>
<string name="see_new_posts">Những tút mới</string>
<string name="load_missing_posts">Tải tút chưa đọc</string>
<string name="follow_back">Theo dõi lại</string>
<string name="button_follow_pending">Đang chờ</string>
@ -599,8 +600,12 @@
<string name="manage_user_lists">Quản lý danh sách %s xuất hiện trên</string>
<string name="remove_from_list">Xóa khỏi danh sách</string>
<string name="confirm_remove_list_member">Xóa người này?</string>
<string name="no_followed_hashtags_title">Theo dõi những hashtag bạn thích</string>
<string name="no_followed_hashtags_subtitle">Chúng sẽ xuất hiện ở đây</string>
<string name="no_lists_title">Sắp xếp bảng tin bằng Danh sách</string>
<string name="no_lists_subtitle">Danh sách sẽ xuất hiện ở đây</string>
<string name="manage_accounts">Thêm hoặc đổi tài khoản</string>
<plurals name="x_posts_recently">
<item quantity="other">%,d tút mới</item>
</plurals>
<string name="see_new_posts">Đọc những tút mới</string>
</resources>

View File

@ -2,29 +2,29 @@
<resources>
<string name="sk_pinned_posts">置顶</string>
<string name="sk_delete_and_redraft">删除并重新编辑</string>
<string name="sk_confirm_delete_and_redraft_title">删除并重新编辑</string>
<string name="sk_confirm_delete_and_redraft">确定要删除并重新编辑此文吗?</string>
<string name="sk_confirm_delete_and_redraft_title">删除并重新编辑</string>
<string name="sk_confirm_delete_and_redraft">确定要删除并重新编辑此文吗?</string>
<string name="sk_pin_post">置顶</string>
<string name="sk_confirm_pin_post_title">置顶</string>
<string name="sk_confirm_pin_post">你确定要在资料页置顶此文吗?</string>
<string name="sk_pinning">正在置顶文…</string>
<string name="sk_confirm_pin_post_title">置顶</string>
<string name="sk_confirm_pin_post">你确定要在资料页置顶此文吗?</string>
<string name="sk_pinning">正在置顶文…</string>
<string name="sk_unpin_post">取消置顶</string>
<string name="sk_confirm_unpin_post_title">取消文置顶</string>
<string name="sk_confirm_unpin_post">你确定不再置顶此文吗?</string>
<string name="sk_confirm_unpin_post_title">取消文置顶</string>
<string name="sk_confirm_unpin_post">你确定不再置顶此文吗?</string>
<string name="sk_unpinning">正在取消置顶…</string>
<string name="sk_image_description">图片描述</string>
<string name="sk_visibility_unlisted">不公开</string>
<string name="sk_federated_timeline">联邦时间轴</string>
<string name="sk_federated_timeline_info_banner">这些是互联实例中最新发布的文。</string>
<string name="sk_federated_timeline_info_banner">这些是互联实例中最新发布的文。</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_settings_show_replies">显示回复</string>
<string name="sk_settings_show_boosts">显示转嘟</string>
<string name="sk_settings_load_new_posts">自动加载新</string>
<string name="sk_settings_load_new_posts">自动加载新</string>
<string name="sk_settings_show_interaction_counts">显示互动次数</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">标记为敏感媒体</string>
<string name="sk_user_post_notifications_on">启用 %s 的文通知</string>
<string name="sk_user_post_notifications_off">关闭 %s 的文通知</string>
<string name="sk_user_post_notifications_on">启用 %s 的文通知</string>
<string name="sk_user_post_notifications_off">关闭 %s 的文通知</string>
<string name="sk_update_available">Megalodon %s 已经可以下载了。</string>
<string name="sk_update_ready">Megalodon %s 已下载,准备安装。</string>
<string name="sk_check_for_update">检查更新</string>
@ -45,8 +45,8 @@
<string name="sk_color_palette_blue"></string>
<string name="sk_color_palette_brown"></string>
<string name="sk_color_palette_yellow"></string>
<string name="sk_notification_type_status"></string>
<string name="sk_notification_type_posts">文通知</string>
<string name="sk_notification_type_status"></string>
<string name="sk_notification_type_posts">文通知</string>
<string name="sk_translate_post">翻译</string>
<string name="sk_translate_show_original">显示原文</string>
<string name="sk_poll_allow_multiple">允许多选</string>
@ -84,8 +84,8 @@
<string name="sk_loading_fediverse_resource_title">在联邦宇宙上查找</string>
<string name="sk_undo_reblog">撤销转嘟</string>
<string name="sk_reblog_with_visibility">转嘟可见性</string>
<string name="sk_quote_post">引用此</string>
<string name="sk_copy_link_to_post">复制文链接</string>
<string name="sk_quote_post">引用此</string>
<string name="sk_copy_link_to_post">复制文链接</string>
<string name="sk_hashtags_you_follow">你关注的标签</string>
<string name="sk_loading_resource_on_instance_title">在 %s 上查找</string>
<string name="sk_resource_not_found">找不到资源</string>
@ -101,27 +101,27 @@
<string name="sk_already_reblogged">已转嘟过</string>
<string name="sk_reply_as">用其他账号回复</string>
<string name="sk_settings_uniform_icon_for_notifications">所有通知的统一图标</string>
<string name="sk_unsent_posts">未发送的</string>
<string name="sk_unsent_posts">未发送的</string>
<string name="sk_confirm_delete_draft_title">删除草稿</string>
<string name="sk_draft">草稿</string>
<string name="sk_schedule">定时</string>
<string name="sk_confirm_delete_scheduled_post_title">删除定时</string>
<string name="sk_confirm_delete_scheduled_post">你确定要删除此定时文吗?</string>
<string name="sk_confirm_delete_scheduled_post_title">删除定时</string>
<string name="sk_confirm_delete_scheduled_post">你确定要删除此定时文吗?</string>
<string name="sk_draft_or_schedule">草稿或定时</string>
<string name="sk_compose_draft">文将保存为草稿。</string>
<string name="sk_compose_draft">文将保存为草稿。</string>
<string name="sk_compose_scheduled">定时于</string>
<string name="sk_draft_saved">草稿已保存</string>
<string name="sk_post_scheduled">文已定时</string>
<string name="sk_post_scheduled">文已定时</string>
<string name="sk_forward_report_to">转嘟给 %s</string>
<string name="sk_confirm_delete_draft">你确定要删除此文草稿吗?</string>
<string name="sk_confirm_delete_draft">你确定要删除此文草稿吗?</string>
<string name="sk_scheduled_too_soon_title">定时时间过早</string>
<string name="sk_scheduled_too_soon">文只能设置为 10 分钟或更晚发送。</string>
<string name="sk_scheduled_too_soon">文只能设置为 10 分钟或更晚发送。</string>
<string name="sk_save_draft">保存为草稿?</string>
<string name="sk_save_changes">保存更改?</string>
<string name="sk_confirm_save_draft">保存草稿?</string>
<string name="sk_confirm_save_changes">保存更改?</string>
<string name="sk_mark_as_draft">标记为草稿</string>
<string name="sk_schedule_post">定时</string>
<string name="sk_schedule_post">定时</string>
<string name="sk_compose_no_schedule">不要定时</string>
<string name="sk_compose_no_draft">不要标记为草稿</string>
<string name="sk_settings_reduce_motion">减少动画效果</string>
@ -151,14 +151,14 @@
<string name="sk_timeline_local">本站</string>
<string name="sk_alt_text_missing">至少有一个附件不包含描述。</string>
<string name="sk_publish_anyway">仍然发布</string>
<string name="sk_notify_posts_info_banner">如果你为某些人启用了嘟文通知,其新嘟文将显示在此处。</string>
<string name="sk_notify_posts_info_banner">如果你为某些人启用了帖文通知,其新帖文将显示在此处。</string>
<string name="sk_timelines">时间线</string>
<string name="sk_edit_timelines">编辑时间线</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_post_edited">编辑</string>
<string name="sk_notification_type_update">编辑</string>
<string name="sk_notification_type_update">编辑</string>
<string name="sk_alt_text_missing_title">缺少 ALT 文本</string>
<string name="sk_timeline_posts"></string>
<string name="sk_timeline_posts"></string>
<string name="sk_timelines_add">添加</string>
<string name="sk_timeline">时间线</string>
<string name="sk_list">列表</string>
@ -223,7 +223,7 @@
<string name="sk_icon_headphones">耳机</string>
<string name="sk_icon_human">人类</string>
<string name="sk_icon_globe">地球</string>
<string name="sk_notify_update">编辑已转嘟</string>
<string name="sk_notify_update">编辑已转嘟</string>
<string name="sk_icon_pin">钉子</string>
<string name="sk_remove_follower_confirm">通过屏蔽并立即解除屏蔽以移除%s的关注者身份</string>
<string name="sk_icon_clapper_board">拍板</string>
@ -248,7 +248,7 @@
<string name="sk_settings_glitch_mode_explanation">如果你的主实例运行 Glitch请启用此功能。Hometown 或 Akkoma 不需要启用。</string>
<string name="sk_sign_ups">用户注册</string>
<string name="sk_new_reports">新举报</string>
<string name="sk_settings_see_new_posts_button">“查看新文” 按钮</string>
<string name="sk_settings_see_new_posts_button">“查看新文” 按钮</string>
<string name="sk_settings_server_version">服务器版本: %s</string>
<string name="sk_notify_poll_results">投票结果</string>
<string name="sk_expand">展开</string>
@ -256,7 +256,7 @@
<string name="sk_unfinished_attachments">正在上传附件</string>
<string name="sk_unfinished_attachments_message">部分附件尚未上传完毕。</string>
<string name="sk_filtered">已过滤:%s</string>
<string name="sk_settings_collapse_long_posts">折叠很长的</string>
<string name="sk_settings_collapse_long_posts">折叠很长的</string>
<string name="sk_settings_prefix_reply_cw_with_re">回复时在 CW 前加上 “re:”</string>
<string name="sk_spectator_mode">旁观模式</string>
<string name="sk_settings_hide_interaction">隐藏互动按钮</string>
@ -287,7 +287,7 @@
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">启用文格式</string>
<string name="sk_settings_content_types">启用文格式</string>
<string name="sk_settings_content_types_explanation">允许在创建文章时设置类似Markdown的内容类型。注意不是所有的实例都支持这个。</string>
<string name="sk_settings_default_content_type">默认的内容类型</string>
<string name="sk_timeline_bubble">Bubble</string>
@ -319,7 +319,7 @@
<string name="sk_disable_pill_shaped_active_indicator">禁用药丸状的活跃选项卡指示器</string>
<string name="sk_settings_true_black">全黑模式</string>
<string name="sk_settings_display_pronouns_in_timelines">在时间线上显示性别代词</string>
<string name="sk_settings_emoji_reactions_explanation">显示对文的表情回应,并允许你添加自己的表情回应。许多 Fediverse 服务器支持此功能,但 Mastodon 不支持。</string>
<string name="sk_settings_emoji_reactions_explanation">显示对文的表情回应,并允许你添加自己的表情回应。许多 Fediverse 服务器支持此功能,但 Mastodon 不支持。</string>
<string name="sk_settings_emoji_reactions_in_lists">在时间线中显示表情回应</string>
<string name="sk_settings_emoji_reactions_in_lists_explanation">是否在时间线中显示表情回应。如果此选项为关闭,则只有在查看对话时才会显示表情回应。</string>
<string name="sk_button_react">用表情回应</string>
@ -349,12 +349,12 @@
<string name="sk_icon_doctor">医生</string>
<string name="sk_icon_diamond">钻石</string>
<string name="sk_icon_umbrella">雨伞</string>
<string name="sk_edit_timeline_tag_main">包含标签的文…</string>
<string name="sk_edit_timeline_tag_main">包含标签的文…</string>
<string name="sk_edit_timeline_tag_none">…但都不包含</string>
<string name="sk_edit_timeline_tag_any">…或包含其中任何一个</string>
<string name="sk_edit_timeline_tag_hint">输入标签…</string>
<string name="sk_edit_timeline_tags_hint">输入标签…</string>
<string name="sk_hashtag_timeline_local_only_switch">仅显示本地文?</string>
<string name="sk_hashtag_timeline_local_only_switch">仅显示本地文?</string>
<string name="sk_add_timeline_tag_error_empty">标签不可为空</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_settings_prefix_replies_always">回复至任何人</string>
@ -370,29 +370,29 @@
<string name="sk_tab_profile">个人资料</string>
<string name="sk_settings_show_labels_in_navigation_bar">在导航栏中显示选项卡标签</string>
<string name="sk_reacted_with">%1$s 回应了 %2$s</string>
<string name="sk_bubble_timeline_info_banner">这些都是实例管理员从网络中最新精选出来的文。</string>
<string name="sk_bubble_timeline_info_banner">这些都是实例管理员从网络中最新精选出来的文。</string>
<string name="sk_search_fediverse">搜索联邦宇宙</string>
<string name="sk_time_seconds">%d 秒</string>
<string name="sk_settings_show_emoji_reactions_only_opened">仅当文被打开时</string>
<string name="sk_settings_show_emoji_reactions_only_opened">仅当文被打开时</string>
<string name="sk_time_hours">%d 时</string>
<string name="sk_settings_show_emoji_reactions_hide_empty">隐藏空的表情回应</string>
<string name="sk_settings_show_emoji_reactions">在时间线中显示表情回应</string>
<plurals name="sk_posts_count_label">
<item quantity="other"></item>
<item quantity="other"></item>
</plurals>
<string name="sk_suicide_search_terms">自杀</string>
<string name="sk_load_missing_posts_above">加载较新的</string>
<string name="sk_load_missing_posts_above">加载较新的</string>
<string name="sk_time_days">%d 天</string>
<string name="sk_settings_show_emoji_reactions_always">始终显示添加按钮</string>
<string name="sk_search_suicide_hotlines">查找求助热线</string>
<string name="sk_do_not_show_again">下次不再显示</string>
<string name="sk_trending_posts_info_banner">这些文正在联邦宇宙上引起关注。</string>
<string name="sk_load_missing_posts_below">加载较旧的</string>
<string name="sk_trending_posts_info_banner">这些文正在联邦宇宙上引起关注。</string>
<string name="sk_load_missing_posts_below">加载较旧的</string>
<string name="sk_search_suicide_title">以防你遇到困难…</string>
<string name="sk_time_minutes">%d 分</string>
<string name="sk_search_suicide_message">如果你正在寻找一个不自杀的迹象,这就是。如果你遇到困难,请考虑拨打当地的自杀热线。</string>
<string name="sk_trending_links_info_banner">这些新闻故事正在联邦宇宙上被讨论。</string>
<string name="sk_post_contains_media">文包含媒体</string>
<string name="sk_post_contains_media">文包含媒体</string>
<string name="sk_blocked_accounts">已屏蔽账号</string>
<string name="sk_muted_accounts">已静音账号</string>
<string name="sk_settings_like_icon">使用心形作为收藏图标</string>
@ -401,4 +401,8 @@
<string name="sk_settings_color_palette_default">默认(%s</string>
<string name="sk_settings_underlined_links">链接加下划线</string>
<string name="sk_edit_alt_text">编辑 ALT 文本</string>
<string name="sk_settings_default_visibility">默认发帖可见性</string>
<string name="sk_settings_lock_account">手动批准新关注者</string>
<string name="sk_timeline_cache_cleared">已清除主页时间线缓存</string>
<string name="sk_settings_clear_timeline_cache">清除主页时间线缓存</string>
</resources>

View File

@ -608,4 +608,10 @@
<plurals name="x_posts_recently">
<item quantity="other">%,d 最近發嘟</item>
</plurals>
<string name="create_list">新增列表</string>
<string name="step_x_of_y">%2$d 中之第 %1$d 步</string>
<string name="create">新增</string>
<string name="manage_list_members">管理列表成員</string>
<string name="list_no_members">尚無成員</string>
<string name="list_find_users">尋找欲新增之使用者</string>
</resources>

View File

@ -416,4 +416,5 @@
<string name="sk_timeline_cache_cleared">Cleared home timeline cache</string>
<string name="sk_settings_lock_account">Manually approve new followers</string>
<string name="sk_settings_default_visibility">Default posting visibility</string>
<string name="sk_button_mutuals">Mutuals</string>
</resources>

View File

@ -228,6 +228,9 @@
<style name="Widget.Mastodon.M3.Button.Tonal.Icon">
<item name="android:paddingStart">16dp</item>
</style>
<style name="Widget.Mastodon.M3.Button.Tonal.Outlined">
<item name="android:background">@drawable/bg_button_m3_tonal_outlined</item>
</style>
<style name="Widget.Mastodon.M3.Button.Tonal.Error">
<item name="android:background">@drawable/bg_button_m3_tonal_error</item>