Merge branch 'main' into pr/FineFindus/557
This commit is contained in:
@@ -64,8 +64,8 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
|||||||
fediHandle
|
fediHandle
|
||||||
.<MastodonAPIRequest<?>>map(handle ->
|
.<MastodonAPIRequest<?>>map(handle ->
|
||||||
UiUtils.lookupAccountHandle(this, accountId, handle, callback))
|
UiUtils.lookupAccountHandle(this, accountId, handle, callback))
|
||||||
.or(() -> Optional.ofNullable(
|
.or(() ->
|
||||||
UiUtils.lookupURL(this, accountId, text.get(), false, callback)))
|
UiUtils.lookupURL(this, accountId, text.get(), callback))
|
||||||
.ifPresent(req ->
|
.ifPresent(req ->
|
||||||
req.wrapProgress(this, R.string.loading, true, d -> {
|
req.wrapProgress(this, R.string.loading, true, d -> {
|
||||||
UiUtils.transformDialogForLookup(this, accountId, isFediUrl ? text.get() : null, d);
|
UiUtils.transformDialogForLookup(this, accountId, isFediUrl ? text.get() : null, d);
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public class GlobalUserPreferences{
|
|||||||
public static boolean compactReblogReplyLine;
|
public static boolean compactReblogReplyLine;
|
||||||
public static boolean confirmBeforeReblog;
|
public static boolean confirmBeforeReblog;
|
||||||
public static boolean allowRemoteLoading;
|
public static boolean allowRemoteLoading;
|
||||||
|
public static AutoRevealMode autoRevealEqualSpoilers;
|
||||||
public static String publishButtonText;
|
public static String publishButtonText;
|
||||||
public static ThemePreference theme;
|
public static ThemePreference theme;
|
||||||
public static ColorPreference color;
|
public static ColorPreference color;
|
||||||
@@ -129,6 +130,7 @@ public class GlobalUserPreferences{
|
|||||||
accountsWithContentTypesEnabled=prefs.getStringSet("accountsWithContentTypesEnabled", new HashSet<>());
|
accountsWithContentTypesEnabled=prefs.getStringSet("accountsWithContentTypesEnabled", new HashSet<>());
|
||||||
accountsDefaultContentTypes=fromJson(prefs.getString("accountsDefaultContentTypes", null), accountsDefaultContentTypesType, new HashMap<>());
|
accountsDefaultContentTypes=fromJson(prefs.getString("accountsDefaultContentTypes", null), accountsDefaultContentTypesType, new HashMap<>());
|
||||||
allowRemoteLoading=prefs.getBoolean("allowRemoteLoading", true);
|
allowRemoteLoading=prefs.getBoolean("allowRemoteLoading", true);
|
||||||
|
autoRevealEqualSpoilers=AutoRevealMode.valueOf(prefs.getString("autoRevealEqualSpoilers", AutoRevealMode.THREADS.name()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.PINK.name()));
|
color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.PINK.name()));
|
||||||
@@ -179,6 +181,7 @@ public class GlobalUserPreferences{
|
|||||||
.putStringSet("accountsWithContentTypesEnabled", accountsWithContentTypesEnabled)
|
.putStringSet("accountsWithContentTypesEnabled", accountsWithContentTypesEnabled)
|
||||||
.putString("accountsDefaultContentTypes", gson.toJson(accountsDefaultContentTypes))
|
.putString("accountsDefaultContentTypes", gson.toJson(accountsDefaultContentTypes))
|
||||||
.putBoolean("allowRemoteLoading", allowRemoteLoading)
|
.putBoolean("allowRemoteLoading", allowRemoteLoading)
|
||||||
|
.putString("autoRevealEqualSpoilers", autoRevealEqualSpoilers.name())
|
||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,4 +201,10 @@ public class GlobalUserPreferences{
|
|||||||
LIGHT,
|
LIGHT,
|
||||||
DARK
|
DARK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum AutoRevealMode {
|
||||||
|
NEVER,
|
||||||
|
THREADS,
|
||||||
|
DISCUSSIONS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -848,10 +848,10 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
updateScheduledAt(scheduledAt != null ? scheduledAt : scheduledStatus != null ? scheduledStatus.scheduledAt : null);
|
updateScheduledAt(scheduledAt != null ? scheduledAt : scheduledStatus != null ? scheduledStatus.scheduledAt : null);
|
||||||
buildLanguageSelector(languageButton);
|
buildLanguageSelector(languageButton);
|
||||||
|
|
||||||
|
if (isInstancePixelfed()) spoilerBtn.setVisibility(View.GONE);
|
||||||
if (isInstancePixelfed() || (editingStatus != null && scheduledStatus == null)) {
|
if (isInstancePixelfed() || (editingStatus != null && scheduledStatus == null)) {
|
||||||
// editing an already published post
|
// editing an already published post
|
||||||
draftsBtn.setVisibility(View.GONE);
|
draftsBtn.setVisibility(View.GONE);
|
||||||
spoilerBtn.setVisibility(View.GONE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import com.squareup.otto.Subscribe;
|
|||||||
import org.joinmastodon.android.BuildConfig;
|
import org.joinmastodon.android.BuildConfig;
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
|
import org.joinmastodon.android.GlobalUserPreferences.AutoRevealMode;
|
||||||
import org.joinmastodon.android.GlobalUserPreferences.ColorPreference;
|
import org.joinmastodon.android.GlobalUserPreferences.ColorPreference;
|
||||||
import org.joinmastodon.android.MainActivity;
|
import org.joinmastodon.android.MainActivity;
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
@@ -85,8 +86,8 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
|
|||||||
private ArrayList<Item> items=new ArrayList<>();
|
private ArrayList<Item> items=new ArrayList<>();
|
||||||
private ThemeItem themeItem;
|
private ThemeItem themeItem;
|
||||||
private NotificationPolicyItem notificationPolicyItem;
|
private NotificationPolicyItem notificationPolicyItem;
|
||||||
private SwitchItem showNewPostsItem, glitchModeItem, compactReblogReplyLineItem;
|
private SwitchItem showNewPostsItem, glitchModeItem, compactReblogReplyLineItem, alwaysRevealSpoilersItem;
|
||||||
private ButtonItem defaultContentTypeButtonItem;
|
private ButtonItem defaultContentTypeButtonItem, autoRevealSpoilersItem;
|
||||||
private String accountID;
|
private String accountID;
|
||||||
private boolean needUpdateNotificationSettings;
|
private boolean needUpdateNotificationSettings;
|
||||||
private boolean needAppRestart;
|
private boolean needAppRestart;
|
||||||
@@ -189,9 +190,18 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
|
|||||||
GlobalUserPreferences.showInteractionCounts=i.checked;
|
GlobalUserPreferences.showInteractionCounts=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
items.add(new SwitchItem(R.string.sk_settings_always_reveal_content_warnings, R.drawable.ic_fluent_chat_warning_24_regular, GlobalUserPreferences.alwaysExpandContentWarnings, i->{
|
items.add(alwaysRevealSpoilersItem = new SwitchItem(R.string.sk_settings_always_reveal_content_warnings, R.drawable.ic_fluent_chat_warning_24_regular, GlobalUserPreferences.alwaysExpandContentWarnings, i->{
|
||||||
GlobalUserPreferences.alwaysExpandContentWarnings=i.checked;
|
GlobalUserPreferences.alwaysExpandContentWarnings=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
|
if (list.findViewHolderForAdapterPosition(items.indexOf(autoRevealSpoilersItem)) instanceof ButtonViewHolder bvh) bvh.rebind();
|
||||||
|
}));
|
||||||
|
items.add(autoRevealSpoilersItem = new ButtonItem(R.string.sk_settings_auto_reveal_equal_spoilers, R.drawable.ic_fluent_eye_24_regular, b->{
|
||||||
|
PopupMenu popupMenu=new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL);
|
||||||
|
popupMenu.inflate(R.menu.settings_auto_reveal_spoiler);
|
||||||
|
popupMenu.setOnMenuItemClickListener(i -> onAutoRevealSpoilerClick(i, b));
|
||||||
|
b.setOnTouchListener(popupMenu.getDragToOpenListener());
|
||||||
|
b.setOnClickListener(v->popupMenu.show());
|
||||||
|
onAutoRevealSpoilerChanged(b);
|
||||||
}));
|
}));
|
||||||
items.add(new SwitchItem(R.string.sk_tabs_disable_swipe, R.drawable.ic_fluent_swipe_right_24_regular, GlobalUserPreferences.disableSwipe, i->{
|
items.add(new SwitchItem(R.string.sk_tabs_disable_swipe, R.drawable.ic_fluent_swipe_right_24_regular, GlobalUserPreferences.disableSwipe, i->{
|
||||||
GlobalUserPreferences.disableSwipe=i.checked;
|
GlobalUserPreferences.disableSwipe=i.checked;
|
||||||
@@ -276,7 +286,7 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
|
|||||||
GlobalUserPreferences.collapseLongPosts=i.checked;
|
GlobalUserPreferences.collapseLongPosts=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
items.add(new SwitchItem(R.string.sk_settings_hide_interaction, R.drawable.ic_fluent_eye_24_regular, GlobalUserPreferences.spectatorMode, i->{
|
items.add(new SwitchItem(R.string.sk_settings_hide_interaction, R.drawable.ic_fluent_star_off_24_regular, GlobalUserPreferences.spectatorMode, i->{
|
||||||
GlobalUserPreferences.spectatorMode=i.checked;
|
GlobalUserPreferences.spectatorMode=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
needAppRestart=true;
|
needAppRestart=true;
|
||||||
@@ -531,6 +541,36 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean onAutoRevealSpoilerClick(MenuItem item, Button btn) {
|
||||||
|
int id = item.getItemId();
|
||||||
|
|
||||||
|
AutoRevealMode mode = AutoRevealMode.NEVER;
|
||||||
|
if (id == R.id.auto_reveal_threads) mode = AutoRevealMode.THREADS;
|
||||||
|
else if (id == R.id.auto_reveal_discussions) mode = AutoRevealMode.DISCUSSIONS;
|
||||||
|
|
||||||
|
GlobalUserPreferences.alwaysExpandContentWarnings = false;
|
||||||
|
GlobalUserPreferences.autoRevealEqualSpoilers = mode;
|
||||||
|
GlobalUserPreferences.save();
|
||||||
|
onAutoRevealSpoilerChanged(btn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onAutoRevealSpoilerChanged(Button b) {
|
||||||
|
if (GlobalUserPreferences.alwaysExpandContentWarnings) {
|
||||||
|
b.setText(R.string.sk_settings_auto_reveal_anyone);
|
||||||
|
} else {
|
||||||
|
b.setText(switch(GlobalUserPreferences.autoRevealEqualSpoilers){
|
||||||
|
case THREADS -> R.string.sk_settings_auto_reveal_author;
|
||||||
|
case DISCUSSIONS -> R.string.sk_settings_auto_reveal_anyone;
|
||||||
|
default -> R.string.sk_settings_auto_reveal_nobody;
|
||||||
|
});
|
||||||
|
if (alwaysRevealSpoilersItem.checked != GlobalUserPreferences.alwaysExpandContentWarnings) {
|
||||||
|
alwaysRevealSpoilersItem.checked = GlobalUserPreferences.alwaysExpandContentWarnings;
|
||||||
|
if (list.findViewHolderForAdapterPosition(items.indexOf(alwaysRevealSpoilersItem)) instanceof SwitchViewHolder svh) svh.rebind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onTrueBlackThemeChanged(SwitchItem item){
|
private void onTrueBlackThemeChanged(SwitchItem item){
|
||||||
GlobalUserPreferences.trueBlackTheme=item.checked;
|
GlobalUserPreferences.trueBlackTheme=item.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
@@ -560,14 +600,14 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
|
|||||||
|
|
||||||
private boolean onContentTypeChanged(MenuItem item, Button btn){
|
private boolean onContentTypeChanged(MenuItem item, Button btn){
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
ContentType contentType = switch (id) {
|
|
||||||
case R.id.content_type_plain -> ContentType.PLAIN;
|
ContentType contentType = null;
|
||||||
case R.id.content_type_html -> ContentType.HTML;
|
if (id == R.id.content_type_plain) contentType = ContentType.PLAIN;
|
||||||
case R.id.content_type_markdown -> ContentType.MARKDOWN;
|
else if (id == R.id.content_type_html) contentType = ContentType.HTML;
|
||||||
case R.id.content_type_bbcode -> ContentType.BBCODE;
|
else if (id == R.id.content_type_markdown) contentType = ContentType.MARKDOWN;
|
||||||
case R.id.content_type_misskey_markdown -> ContentType.MISSKEY_MARKDOWN;
|
else if (id == R.id.content_type_bbcode) contentType = ContentType.BBCODE;
|
||||||
default -> null;
|
else if (id == R.id.content_type_misskey_markdown) contentType = ContentType.MISSKEY_MARKDOWN;
|
||||||
};
|
|
||||||
GlobalUserPreferences.accountsDefaultContentTypes.put(accountID, contentType);
|
GlobalUserPreferences.accountsDefaultContentTypes.put(accountID, contentType);
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
btn.setText(getContentTypeString(contentType));
|
btn.setText(getContentTypeString(contentType));
|
||||||
|
|||||||
@@ -164,13 +164,29 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>
|
|||||||
protected void removeStatus(Status status){
|
protected void removeStatus(Status status){
|
||||||
data.remove(status);
|
data.remove(status);
|
||||||
preloadedData.remove(status);
|
preloadedData.remove(status);
|
||||||
int index=-1;
|
int index=-1, ancestorFirstIndex = -1, ancestorLastIndex = -1;
|
||||||
for(int i=0;i<displayItems.size();i++){
|
for(int i=0;i<displayItems.size();i++){
|
||||||
if(status.id.equals(displayItems.get(i).parentID)){
|
StatusDisplayItem item = displayItems.get(i);
|
||||||
|
if(status.id.equals(item.parentID)){
|
||||||
index=i;
|
index=i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (item.parentID.equals(status.inReplyToId)) {
|
||||||
|
if (ancestorFirstIndex == -1) ancestorFirstIndex = i;
|
||||||
|
ancestorLastIndex = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// did we find an ancestor that is also the status' neighbor?
|
||||||
|
if (ancestorFirstIndex >= 0 && ancestorLastIndex == index - 1) {
|
||||||
|
for (int i = ancestorFirstIndex; i <= ancestorLastIndex; i++) {
|
||||||
|
StatusDisplayItem item = displayItems.get(i);
|
||||||
|
// update ancestor to have no descendant anymore
|
||||||
|
if (item.parentID.equals(status.inReplyToId)) item.hasDescendantNeighbor = false;
|
||||||
|
}
|
||||||
|
adapter.notifyItemRangeChanged(ancestorFirstIndex, ancestorLastIndex - ancestorFirstIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(index==-1)
|
if(index==-1)
|
||||||
return;
|
return;
|
||||||
int lastIndex;
|
int lastIndex;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
|
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
|
import org.joinmastodon.android.GlobalUserPreferences.AutoRevealMode;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusContext;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusContext;
|
||||||
@@ -38,6 +39,7 @@ import java.util.Collections;
|
|||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -119,7 +121,10 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(StatusContext result){
|
public void onSuccess(StatusContext result){
|
||||||
if (getContext() == null) return;
|
if (getContext() == null) return;
|
||||||
|
Map<String, Status> oldData = null;
|
||||||
if(refreshing){
|
if(refreshing){
|
||||||
|
oldData = new HashMap<>(data.size());
|
||||||
|
for (Status s : data) oldData.put(s.id, s);
|
||||||
data.clear();
|
data.clear();
|
||||||
ancestryMap.clear();
|
ancestryMap.clear();
|
||||||
displayItems.clear();
|
displayItems.clear();
|
||||||
@@ -151,6 +156,23 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
|
|||||||
adapter.notifyItemRemoved(prependedCount);
|
adapter.notifyItemRemoved(prependedCount);
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Status s : data) {
|
||||||
|
Status oldStatus = oldData == null ? null : oldData.get(s.id);
|
||||||
|
// restore previous spoiler/filter revealed states when refreshing
|
||||||
|
if (oldStatus != null) {
|
||||||
|
s.spoilerRevealed = oldStatus.spoilerRevealed;
|
||||||
|
s.filterRevealed = oldStatus.filterRevealed;
|
||||||
|
} else if (GlobalUserPreferences.autoRevealEqualSpoilers != AutoRevealMode.NEVER &&
|
||||||
|
s.spoilerText != null &&
|
||||||
|
s.spoilerText.equals(mainStatus.spoilerText) &&
|
||||||
|
mainStatus.spoilerRevealed) {
|
||||||
|
if (GlobalUserPreferences.autoRevealEqualSpoilers == AutoRevealMode.DISCUSSIONS || Objects.equals(mainStatus.account.id, s.account.id)) {
|
||||||
|
s.spoilerRevealed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dataLoaded();
|
dataLoaded();
|
||||||
if(refreshing){
|
if(refreshing){
|
||||||
refreshDone();
|
refreshDone();
|
||||||
@@ -189,6 +211,10 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
|
|||||||
protected Object maybeApplyMainStatus() {
|
protected Object maybeApplyMainStatus() {
|
||||||
if (updatedStatus == null || !contextInitiallyRendered) return null;
|
if (updatedStatus == null || !contextInitiallyRendered) return null;
|
||||||
|
|
||||||
|
// restore revealed states for main status because it gets updated after doLoadData
|
||||||
|
updatedStatus.filterRevealed = mainStatus.filterRevealed;
|
||||||
|
updatedStatus.spoilerRevealed = mainStatus.spoilerRevealed;
|
||||||
|
|
||||||
// returning fired event object to facilitate testing
|
// returning fired event object to facilitate testing
|
||||||
Object event;
|
Object event;
|
||||||
if (updatedStatus.editedAt != null &&
|
if (updatedStatus.editedAt != null &&
|
||||||
@@ -312,15 +338,65 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void onStatusCreated(StatusCreatedEvent ev){
|
protected void onStatusCreated(StatusCreatedEvent ev){
|
||||||
if(ev.status.inReplyToId!=null && getStatusByID(ev.status.inReplyToId)!=null){
|
if (ev.status.inReplyToId == null) return;
|
||||||
data.add(ev.status);
|
Status repliedToStatus = getStatusByID(ev.status.inReplyToId);
|
||||||
onAppendItems(Collections.singletonList(ev.status));
|
if (repliedToStatus == null) return;
|
||||||
|
NeighborAncestryInfo ancestry = ancestryMap.get(repliedToStatus.id);
|
||||||
|
|
||||||
|
int nextDisplayItemsIndex = -1, indexOfPreviousDisplayItem = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < displayItems.size(); i++) {
|
||||||
|
StatusDisplayItem item = displayItems.get(i);
|
||||||
|
if (repliedToStatus.id.equals(item.parentID)) {
|
||||||
|
// saving the replied-to status' display items index to eventually reach the last one
|
||||||
|
indexOfPreviousDisplayItem = i;
|
||||||
|
item.hasDescendantNeighbor = true;
|
||||||
|
} else if (indexOfPreviousDisplayItem >= 0 && nextDisplayItemsIndex == -1) {
|
||||||
|
// previous display item was the replied-to status' display items
|
||||||
|
nextDisplayItemsIndex = i;
|
||||||
|
// nothing left to do if there's no other reply to that status
|
||||||
|
if (ancestry.descendantNeighbor == null) break;
|
||||||
|
}
|
||||||
|
if (ancestry.descendantNeighbor != null && item.parentID.equals(ancestry.descendantNeighbor.id)) {
|
||||||
|
// existing reply shall no longer have the replied-to status as its neighbor
|
||||||
|
item.hasAncestoringNeighbor = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fall back to inserting the item at the end
|
||||||
|
nextDisplayItemsIndex = nextDisplayItemsIndex >= 0 ? nextDisplayItemsIndex : displayItems.size();
|
||||||
|
int nextDataIndex = data.indexOf(repliedToStatus) + 1;
|
||||||
|
|
||||||
|
// if replied-to status already has another reply...
|
||||||
|
if (ancestry.descendantNeighbor != null) {
|
||||||
|
// update the reply's ancestry to remove its ancestoring neighbor (as we did above)
|
||||||
|
ancestryMap.get(ancestry.descendantNeighbor.id).ancestoringNeighbor = null;
|
||||||
|
// make sure the existing reply has a reply line
|
||||||
|
if (nextDataIndex < data.size() &&
|
||||||
|
!(displayItems.get(nextDisplayItemsIndex) instanceof ReblogOrReplyLineStatusDisplayItem)) {
|
||||||
|
Status nextStatus = data.get(nextDataIndex);
|
||||||
|
if (!nextStatus.account.id.equals(repliedToStatus.account.id)) {
|
||||||
|
// create reply line manually since we're not building that status' items
|
||||||
|
displayItems.add(nextDisplayItemsIndex, StatusDisplayItem.buildReplyLine(
|
||||||
|
this, nextStatus, accountID, nextStatus, repliedToStatus.account, false
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update replied-to status' ancestry
|
||||||
|
ancestry.descendantNeighbor = ev.status;
|
||||||
|
|
||||||
|
// add ancestry for newly created status before building its display items
|
||||||
|
ancestryMap.put(ev.status.id, new NeighborAncestryInfo(ev.status, null, repliedToStatus));
|
||||||
|
displayItems.addAll(nextDisplayItemsIndex, buildDisplayItems(ev.status));
|
||||||
|
data.add(nextDataIndex, ev.status);
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemEnabled(String id){
|
public boolean isItemEnabled(String id){
|
||||||
return !id.equals(mainStatus.id);
|
return !id.equals(mainStatus.id) || !mainStatus.filterRevealed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -105,6 +105,21 @@ public abstract class StatusDisplayItem{
|
|||||||
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, false, filterContext);
|
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, false, filterContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ReblogOrReplyLineStatusDisplayItem buildReplyLine(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parent, Account account, boolean threadReply) {
|
||||||
|
String parentID = parent.getID();
|
||||||
|
String text = threadReply ? fragment.getString(R.string.sk_show_thread)
|
||||||
|
: account == null ? fragment.getString(R.string.sk_in_reply)
|
||||||
|
: GlobalUserPreferences.compactReblogReplyLine && status.reblog != null ? account.displayName
|
||||||
|
: fragment.getString(R.string.in_reply_to, account.displayName);
|
||||||
|
String fullText = threadReply ? fragment.getString(R.string.sk_show_thread)
|
||||||
|
: account == null ? fragment.getString(R.string.sk_in_reply)
|
||||||
|
: fragment.getString(R.string.in_reply_to, account.displayName);
|
||||||
|
return new ReblogOrReplyLineStatusDisplayItem(
|
||||||
|
parentID, fragment, text, account == null ? List.of() : account.emojis,
|
||||||
|
R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, boolean disableTranslate, Filter.FilterContext filterContext){
|
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, boolean disableTranslate, Filter.FilterContext filterContext){
|
||||||
String parentID=parentObject.getID();
|
String parentID=parentObject.getID();
|
||||||
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
||||||
@@ -120,17 +135,7 @@ public abstract class StatusDisplayItem{
|
|||||||
|
|
||||||
if(statusForContent.inReplyToAccountId!=null && !(threadReply && fragment instanceof ThreadFragment)){
|
if(statusForContent.inReplyToAccountId!=null && !(threadReply && fragment instanceof ThreadFragment)){
|
||||||
Account account = knownAccounts.get(statusForContent.inReplyToAccountId);
|
Account account = knownAccounts.get(statusForContent.inReplyToAccountId);
|
||||||
String text = threadReply ? fragment.getString(R.string.sk_show_thread)
|
replyLine = buildReplyLine(fragment, status, accountID, parentObject, account, threadReply);
|
||||||
: account == null ? fragment.getString(R.string.sk_in_reply)
|
|
||||||
: GlobalUserPreferences.compactReblogReplyLine && status.reblog != null ? account.displayName
|
|
||||||
: fragment.getString(R.string.in_reply_to, account.displayName);
|
|
||||||
String fullText = threadReply ? fragment.getString(R.string.sk_show_thread)
|
|
||||||
: account == null ? fragment.getString(R.string.sk_in_reply)
|
|
||||||
: fragment.getString(R.string.in_reply_to, account.displayName);
|
|
||||||
replyLine = new ReblogOrReplyLineStatusDisplayItem(
|
|
||||||
parentID, fragment, text, account == null ? List.of() : account.emojis,
|
|
||||||
R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status.reblog!=null){
|
if(status.reblog!=null){
|
||||||
|
|||||||
@@ -1053,43 +1053,43 @@ public class UiUtils {
|
|||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void lookupStatus(Context context, Status queryStatus, String targetAccountID, @Nullable String sourceAccountID, Consumer<Status> resultConsumer) {
|
public static Optional<MastodonAPIRequest<SearchResults>> lookupStatus(Context context, Status queryStatus, String targetAccountID, @Nullable String sourceAccountID, Consumer<Status> resultConsumer) {
|
||||||
lookup(context, queryStatus, targetAccountID, sourceAccountID, GetSearchResults.Type.STATUSES, resultConsumer, results ->
|
return lookup(context, queryStatus, targetAccountID, sourceAccountID, GetSearchResults.Type.STATUSES, resultConsumer, results ->
|
||||||
!results.statuses.isEmpty() ? Optional.of(results.statuses.get(0)) : Optional.empty()
|
!results.statuses.isEmpty() ? Optional.of(results.statuses.get(0)) : Optional.empty()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void lookupAccount(Context context, Account queryAccount, String targetAccountID, @Nullable String sourceAccountID, Consumer<Account> resultConsumer) {
|
public static Optional<MastodonAPIRequest<SearchResults>> lookupAccount(Context context, Account queryAccount, String targetAccountID, @Nullable String sourceAccountID, Consumer<Account> resultConsumer) {
|
||||||
lookup(context, queryAccount, targetAccountID, sourceAccountID, GetSearchResults.Type.ACCOUNTS, resultConsumer, results ->
|
return lookup(context, queryAccount, targetAccountID, sourceAccountID, GetSearchResults.Type.ACCOUNTS, resultConsumer, results ->
|
||||||
!results.accounts.isEmpty() ? Optional.of(results.accounts.get(0)) : Optional.empty()
|
!results.accounts.isEmpty() ? Optional.of(results.accounts.get(0)) : Optional.empty()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Searchable> void lookup(Context context, T query, String targetAccountID, @Nullable String sourceAccountID, @Nullable GetSearchResults.Type type, Consumer<T> resultConsumer, Function<SearchResults, Optional<T>> extractResult) {
|
public static <T extends Searchable> Optional<MastodonAPIRequest<SearchResults>> lookup(Context context, T query, String targetAccountID, @Nullable String sourceAccountID, @Nullable GetSearchResults.Type type, Consumer<T> resultConsumer, Function<SearchResults, Optional<T>> extractResult) {
|
||||||
if (sourceAccountID != null && targetAccountID.startsWith(sourceAccountID.substring(0, sourceAccountID.indexOf('_')))) {
|
if (sourceAccountID != null && targetAccountID.startsWith(sourceAccountID.substring(0, sourceAccountID.indexOf('_')))) {
|
||||||
resultConsumer.accept(query);
|
resultConsumer.accept(query);
|
||||||
return;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
new GetSearchResults(query.getQuery(), type, true).setCallback(new Callback<>() {
|
return Optional.of(new GetSearchResults(query.getQuery(), type, true).setCallback(new Callback<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(SearchResults results) {
|
public void onSuccess(SearchResults results) {
|
||||||
Optional<T> result = extractResult.apply(results);
|
Optional<T> result = extractResult.apply(results);
|
||||||
if (result.isPresent()) resultConsumer.accept(result.get());
|
if (result.isPresent()) resultConsumer.accept(result.get());
|
||||||
else {
|
else {
|
||||||
Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
|
||||||
resultConsumer.accept(null);
|
resultConsumer.accept(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(ErrorResponse error) {
|
public void onError(ErrorResponse error) {
|
||||||
error.showToast(context);
|
error.showToast(context);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.wrapProgress((Activity) context, R.string.loading, true,
|
.wrapProgress((Activity) context, R.string.loading, true,
|
||||||
d -> transformDialogForLookup(context, targetAccountID, null, d))
|
d -> transformDialogForLookup(context, targetAccountID, null, d))
|
||||||
.exec(targetAccountID);
|
.exec(targetAccountID));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void transformDialogForLookup(Context context, String accountID, @Nullable String url, ProgressDialog dialog) {
|
public static void transformDialogForLookup(Context context, String accountID, @Nullable String url, ProgressDialog dialog) {
|
||||||
@@ -1127,15 +1127,15 @@ public class UiUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void openURL(Context context, String accountID, String url, boolean launchBrowser) {
|
public static void openURL(Context context, String accountID, String url, boolean launchBrowser) {
|
||||||
lookupURL(context, accountID, url, launchBrowser, (clazz, args) -> {
|
lookupURL(context, accountID, url, (clazz, args) -> {
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
if (args.containsKey("error")) Toast.makeText(context, args.getString("error"), Toast.LENGTH_SHORT).show();
|
if (args != null && args.containsKey("error")) Toast.makeText(context, args.getString("error"), Toast.LENGTH_SHORT).show();
|
||||||
if (launchBrowser) launchWebBrowser(context, url);
|
if (launchBrowser) launchWebBrowser(context, url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Nav.go((Activity) context, clazz, args);
|
Nav.go((Activity) context, clazz, args);
|
||||||
}).wrapProgress((Activity) context, R.string.loading, true, d ->
|
}).map(req -> req.wrapProgress((Activity) context, R.string.loading, true, d ->
|
||||||
transformDialogForLookup(context, accountID, url, d));
|
transformDialogForLookup(context, accountID, url, d)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean acctMatches(String accountID, String acct, String queriedUsername, @Nullable String queriedDomain) {
|
public static boolean acctMatches(String accountID, String acct, String queriedUsername, @Nullable String queriedDomain) {
|
||||||
@@ -1158,11 +1158,13 @@ public class UiUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void lookupAccountHandle(Context context, String accountID, String query, BiConsumer<Class<? extends Fragment>, Bundle> go) {
|
public static Optional<MastodonAPIRequest<SearchResults>> lookupAccountHandle(Context context, String accountID, String query, BiConsumer<Class<? extends Fragment>, Bundle> go) {
|
||||||
parseFediverseHandle(query).ifPresentOrElse(
|
return parseFediverseHandle(query).map(
|
||||||
handle -> lookupAccountHandle(context, accountID, handle, go),
|
handle -> lookupAccountHandle(context, accountID, handle, go))
|
||||||
() -> go.accept(null, null)
|
.or(() -> {
|
||||||
);
|
go.accept(null, null);
|
||||||
|
return Optional.empty();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
public static MastodonAPIRequest<SearchResults> lookupAccountHandle(Context context, String accountID, Pair<String, Optional<String>> queryHandle, BiConsumer<Class<? extends Fragment>, Bundle> go) {
|
public static MastodonAPIRequest<SearchResults> lookupAccountHandle(Context context, String accountID, Pair<String, Optional<String>> queryHandle, BiConsumer<Class<? extends Fragment>, Bundle> go) {
|
||||||
String fullHandle = ("@" + queryHandle.first) + (queryHandle.second.map(domain -> "@" + domain).orElse(""));
|
String fullHandle = ("@" + queryHandle.first) + (queryHandle.second.map(domain -> "@" + domain).orElse(""));
|
||||||
@@ -1190,12 +1192,12 @@ public class UiUtils {
|
|||||||
}).exec(accountID);
|
}).exec(accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MastodonAPIRequest<?> lookupURL(Context context, String accountID, String url, boolean launchBrowser, BiConsumer<Class<? extends Fragment>, Bundle> go) {
|
public static Optional<MastodonAPIRequest<?>> lookupURL(Context context, String accountID, String url, BiConsumer<Class<? extends Fragment>, Bundle> go) {
|
||||||
Uri uri = Uri.parse(url);
|
Uri uri = Uri.parse(url);
|
||||||
List<String> path = uri.getPathSegments();
|
List<String> path = uri.getPathSegments();
|
||||||
if (accountID != null && "https".equals(uri.getScheme())) {
|
if (accountID != null && "https".equals(uri.getScheme())) {
|
||||||
if (path.size() == 2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$") && AccountSessionManager.getInstance().getAccount(accountID).domain.equalsIgnoreCase(uri.getAuthority())) {
|
if (path.size() == 2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$") && AccountSessionManager.getInstance().getAccount(accountID).domain.equalsIgnoreCase(uri.getAuthority())) {
|
||||||
return new GetStatusByID(path.get(1))
|
return Optional.of(new GetStatusByID(path.get(1))
|
||||||
.setCallback(new Callback<>() {
|
.setCallback(new Callback<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Status result) {
|
public void onSuccess(Status result) {
|
||||||
@@ -1210,9 +1212,9 @@ public class UiUtils {
|
|||||||
go.accept(null, bundleError(error));
|
go.accept(null, bundleError(error));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.exec(accountID);
|
.exec(accountID));
|
||||||
} else if (looksLikeFediverseUrl(url)) {
|
} else if (looksLikeFediverseUrl(url)) {
|
||||||
return new GetSearchResults(url, null, true)
|
return Optional.of(new GetSearchResults(url, null, true)
|
||||||
.setCallback(new Callback<>() {
|
.setCallback(new Callback<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(SearchResults results) {
|
public void onSuccess(SearchResults results) {
|
||||||
@@ -1230,7 +1232,6 @@ public class UiUtils {
|
|||||||
go.accept(ProfileFragment.class, args);
|
go.accept(ProfileFragment.class, args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (launchBrowser) launchWebBrowser(context, url);
|
|
||||||
go.accept(null, bundleError(context.getString(R.string.sk_resource_not_found)));
|
go.accept(null, bundleError(context.getString(R.string.sk_resource_not_found)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,12 +1240,11 @@ public class UiUtils {
|
|||||||
go.accept(null, bundleError(error));
|
go.accept(null, bundleError(error));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.exec(accountID);
|
.exec(accountID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (launchBrowser) launchWebBrowser(context, url);
|
|
||||||
go.accept(null, null);
|
go.accept(null, null);
|
||||||
return null;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copyText(View v, String text) {
|
public static void copyText(View v, String text) {
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||||
|
<path android:pathData="M3.28 2.22c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.767 0 1.06l4.804 4.805-3.867 0.561C2.05 8.807 1.607 10.168 2.41 10.95l3.815 3.719-0.9 5.251c-0.19 1.103 0.968 1.944 1.958 1.423l4.716-2.479 4.716 2.48c0.99 0.52 2.148-0.32 1.96-1.424l-0.04-0.223 2.085 2.084c0.293 0.293 0.768 0.293 1.061 0 0.293-0.292 0.293-0.767 0-1.06L3.28 2.22zm13.518 15.639l0.345 2.014-4.516-2.374c-0.394-0.207-0.864-0.207-1.257 0l-4.516 2.374 0.862-5.03c0.075-0.437-0.07-0.884-0.388-1.194l-3.654-3.562 4.673-0.679 8.45 8.45zm3.525-7.772l-3.572 3.482 1.06 1.06 3.777-3.68c0.8-0.781 0.359-2.142-0.748-2.303L15.567 7.88l-2.358-4.777c-0.495-1.004-1.926-1.004-2.421 0L9.3 6.117l1.12 1.12 1.578-3.2 2.259 4.577c0.196 0.398 0.577 0.674 1.016 0.738l5.05 0.734z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||||
|
</vector>
|
||||||
12
mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml
Normal file
12
mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/auto_reveal_never"
|
||||||
|
android:title="@string/sk_settings_auto_reveal_nobody" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/auto_reveal_threads"
|
||||||
|
android:title="@string/sk_settings_auto_reveal_author" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/auto_reveal_discussions"
|
||||||
|
android:title="@string/sk_settings_auto_reveal_anyone" />
|
||||||
|
</menu>
|
||||||
@@ -296,4 +296,8 @@
|
|||||||
<string name="sk_no_remote_info_hint">keine Remote-Infos abrufbar</string>
|
<string name="sk_no_remote_info_hint">keine Remote-Infos abrufbar</string>
|
||||||
<string name="sk_error_loading_profile">Konnte das Profil via %s nicht laden</string>
|
<string name="sk_error_loading_profile">Konnte das Profil via %s nicht laden</string>
|
||||||
<string name="sk_settings_allow_remote_loading_explanation">Für vollständigere Auflistung von Follower*innen, Likes und Boosts können die Informationen von der Ursprungs-Instanz geladen werden.</string>
|
<string name="sk_settings_allow_remote_loading_explanation">Für vollständigere Auflistung von Follower*innen, Likes und Boosts können die Informationen von der Ursprungs-Instanz geladen werden.</string>
|
||||||
|
<string name="sk_settings_auto_reveal_equal_spoilers">Gleiche CWs in deren Antworten zeigen</string>
|
||||||
|
<string name="sk_settings_auto_reveal_nobody">Niemand</string>
|
||||||
|
<string name="sk_settings_auto_reveal_author">Autor*in</string>
|
||||||
|
<string name="sk_settings_auto_reveal_anyone">Alle</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -294,4 +294,8 @@
|
|||||||
<string name="sk_timeline_bubble">Bulle</string>
|
<string name="sk_timeline_bubble">Bulle</string>
|
||||||
<string name="sk_instance_info_unavailable">Informations sur l\'instance temporairement indisponibles</string>
|
<string name="sk_instance_info_unavailable">Informations sur l\'instance temporairement indisponibles</string>
|
||||||
<string name="sk_open_in_app_failed">Impossible de l\'ouvrir dans l\'application</string>
|
<string name="sk_open_in_app_failed">Impossible de l\'ouvrir dans l\'application</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading">Charger des informations à partir d\'instances distantes</string>
|
||||||
|
<string name="sk_no_remote_info_hint">informations distantes indisponibles</string>
|
||||||
|
<string name="sk_error_loading_profile">Échec du chargement du profil via %s</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading_explanation">Essayez de récupérer des listes plus précises pour les abonnés, les likes et les boosts en chargeant les informations à partir de l\'instance d\'origine.</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -289,8 +289,13 @@
|
|||||||
<string name="sk_settings_content_types_explanation">Memperbolehkan menetapkan jenis konten seperti Markdown ketika membuat kiriman. Perlu diingat bahwa tidak semua server mendukung ini.</string>
|
<string name="sk_settings_content_types_explanation">Memperbolehkan menetapkan jenis konten seperti Markdown ketika membuat kiriman. Perlu diingat bahwa tidak semua server mendukung ini.</string>
|
||||||
<string name="sk_open_in_app">Buka dalam aplikasi</string>
|
<string name="sk_open_in_app">Buka dalam aplikasi</string>
|
||||||
<string name="sk_external_share_title">Bagikan dengan akun</string>
|
<string name="sk_external_share_title">Bagikan dengan akun</string>
|
||||||
<string name="sk_bubble_timeline_info_banner">Ini adalah kiriman yamg paling terkini oleh orang-orang dalam gelembung server Akkoma Anda.</string>
|
<string name="sk_bubble_timeline_info_banner">Ini adalah kiriman yang paling terkini dari jaringan dikurasikan oleh admin server Anda.</string>
|
||||||
<string name="sk_timeline_bubble">Gelembung</string>
|
<string name="sk_timeline_bubble">Gelembung</string>
|
||||||
<string name="sk_instance_info_unavailable">Info server sementara tidak tersedia</string>
|
<string name="sk_instance_info_unavailable">Info server sementara tidak tersedia</string>
|
||||||
<string name="sk_external_share_or_open_title">Bagikan atau buka dengan akun</string>
|
<string name="sk_external_share_or_open_title">Bagikan atau buka dengan akun</string>
|
||||||
|
<string name="sk_no_remote_info_hint">info jarak jauh tidak tersedia</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading">Muat info dari server jarak jauh</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading_explanation">Coba mendapatkan pendaftaran akurat untuk pengikut cr</string>
|
||||||
|
<string name="sk_error_loading_profile">Gagal memuat profil melalui %s</string>
|
||||||
|
<string name="sk_open_in_app_failed">Tidak dapat buka dalam aplikasi</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -274,4 +274,26 @@
|
|||||||
<string name="sk_compact_reblog_reply_line">Linea boost/risposta compatta</string>
|
<string name="sk_compact_reblog_reply_line">Linea boost/risposta compatta</string>
|
||||||
<string name="sk_reacted_with">ha reagito con %s</string>
|
<string name="sk_reacted_with">ha reagito con %s</string>
|
||||||
<string name="sk_reply_line_above_avatar">Linea \"In risposta a\" sopra l\'avatar</string>
|
<string name="sk_reply_line_above_avatar">Linea \"In risposta a\" sopra l\'avatar</string>
|
||||||
|
<string name="sk_bubble_timeline_info_banner">Questi sono i post più recenti della rete, curati dagli amministratori della tua istanza.</string>
|
||||||
|
<string name="sk_settings_content_types_explanation">Permette di impostare un tipo di contenuto, come Markdown, quando si crea un post. Tieni presente che non tutte le istanze lo supportano.</string>
|
||||||
|
<string name="sk_open_in_app_failed">Impossibile aprire nell\'app</string>
|
||||||
|
<string name="sk_external_share_title">Condividi con l\'account</string>
|
||||||
|
<string name="sk_external_share_or_open_title">Condividi o apri con l\'account</string>
|
||||||
|
<string name="sk_no_remote_info_hint">Informazioni remote non disponibili</string>
|
||||||
|
<string name="sk_error_loading_profile">Impossibile caricare il profilo tramite %s</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading">Carica informazioni da istanze remote</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading_explanation">Cerca di ottenere elenchi più accurati di follower, like e boost caricando le informazioni dall\'istanza di origine.</string>
|
||||||
|
<string name="sk_content_type">Tipo di contenuto</string>
|
||||||
|
<string name="sk_timeline_bubble">Bolla</string>
|
||||||
|
<string name="sk_content_type_unspecified">Non specificato</string>
|
||||||
|
<string name="sk_content_type_plain">Testo semplice</string>
|
||||||
|
<string name="sk_content_type_html">HTML</string>
|
||||||
|
<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">Abilita la formattazione dei post</string>
|
||||||
|
<string name="sk_settings_default_content_type">Tipo di contenuto predefinito</string>
|
||||||
|
<string name="sk_settings_default_content_type_explanation">Ti permette di preselezionare un tipo di contenuto quando si creano nuovi post, sovrascrivendo il valore impostato in \"Preferenze di pubblicazione\".</string>
|
||||||
|
<string name="sk_instance_info_unavailable">Informazioni sull\'istanza temporaneamente non disponibili</string>
|
||||||
|
<string name="sk_open_in_app">Apri nell\'app</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -293,4 +293,8 @@
|
|||||||
<string name="sk_instance_info_unavailable">Сервер тимчасово недоступний</string>
|
<string name="sk_instance_info_unavailable">Сервер тимчасово недоступний</string>
|
||||||
<string name="sk_external_share_or_open_title">Поділитися або відкрити за допомогою облікового запису</string>
|
<string name="sk_external_share_or_open_title">Поділитися або відкрити за допомогою облікового запису</string>
|
||||||
<string name="sk_open_in_app_failed">Не вдалося відкрити в застосунку</string>
|
<string name="sk_open_in_app_failed">Не вдалося відкрити в застосунку</string>
|
||||||
|
<string name="sk_no_remote_info_hint">віддалена інформація недоступна</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading">Завантажити інформацію з віддалених серверів</string>
|
||||||
|
<string name="sk_settings_allow_remote_loading_explanation">Спробуйте отримати точніші списки підписників, вподобань і поширень, завантаживши інформацію з джерела.</string>
|
||||||
|
<string name="sk_error_loading_profile">Не вдалося завантажити профіль на ваш домашній сервер.</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -297,4 +297,8 @@
|
|||||||
<string name="sk_error_loading_profile">Failed loading the profile via %s</string>
|
<string name="sk_error_loading_profile">Failed loading the profile via %s</string>
|
||||||
<string name="sk_settings_allow_remote_loading">Load info from remote instances</string>
|
<string name="sk_settings_allow_remote_loading">Load info from remote instances</string>
|
||||||
<string name="sk_settings_allow_remote_loading_explanation">Try fetching more accurate listings for followers, likes and boosts by loading the information from the instance of origin.</string>
|
<string name="sk_settings_allow_remote_loading_explanation">Try fetching more accurate listings for followers, likes and boosts by loading the information from the instance of origin.</string>
|
||||||
|
<string name="sk_settings_auto_reveal_equal_spoilers">Reveal same CWs in replies from</string>
|
||||||
|
<string name="sk_settings_auto_reveal_nobody">nobody</string>
|
||||||
|
<string name="sk_settings_auto_reveal_author">author</string>
|
||||||
|
<string name="sk_settings_auto_reveal_anyone">everyone</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user