Compare commits
53 Commits
v1.1.5+for
...
v1.1.5+for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2799fcdff | ||
|
|
8e4f402e21 | ||
|
|
10d2949647 | ||
|
|
30ef23308b | ||
|
|
564132ee82 | ||
|
|
1e527e87df | ||
|
|
9692a04275 | ||
|
|
6ece8eb0c1 | ||
|
|
1f33237e8a | ||
|
|
9209508aac | ||
|
|
f750e6ff7e | ||
|
|
f2eecf774b | ||
|
|
98de4e75e0 | ||
|
|
459e32caf8 | ||
|
|
c4ad325e5c | ||
|
|
f55bd6d6cd | ||
|
|
f1ce700c93 | ||
|
|
c18e1e8456 | ||
|
|
1fcd1924c3 | ||
|
|
a1767f0425 | ||
|
|
44d95ca25f | ||
|
|
7432540c29 | ||
|
|
c289f58351 | ||
|
|
711e041ff5 | ||
|
|
0ac3534585 | ||
|
|
57821e0860 | ||
|
|
0dae798c9a | ||
|
|
732e780fd9 | ||
|
|
5577124b7a | ||
|
|
81b82c75a2 | ||
|
|
b32e322749 | ||
|
|
3031cc4561 | ||
|
|
d60abc648c | ||
|
|
a9a0233bb3 | ||
|
|
f6fa9e5122 | ||
|
|
29b4f7c91a | ||
|
|
0a9ee57233 | ||
|
|
94b69a9c1c | ||
|
|
f0209dd1cc | ||
|
|
366e432c18 | ||
|
|
0075c0e779 | ||
|
|
d99dfd4185 | ||
|
|
0309b3ad25 | ||
|
|
7a85532b73 | ||
|
|
7299d947f7 | ||
|
|
adec7b28f1 | ||
|
|
c2563da056 | ||
|
|
64b9e53916 | ||
|
|
86ab6f7b3d | ||
|
|
ed02733524 | ||
|
|
a99af63f34 | ||
|
|
1d900a66fe | ||
|
|
f29acc217d |
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
**Allows you to post publicly without having your post show up in trends, hashtags or public timelines (i.e., in the tabs “Community”, “Federated” and “Posts”).**
|
**Allows you to post publicly without having your post show up in trends, hashtags or public timelines (i.e., in the tabs “Community”, “Federated” and “Posts”).**
|
||||||
|
|
||||||
When posting with Unlisted visibility, your posts will still be publicly accessible in your profile. They will also be shown in people’s Home timelines, but only if they follow you or someone they follow reposted/replied to your post.
|
When posting with Unlisted visibility, your posts will still be publicly accessible in your profile. They will also be shown in people’s Home timelines, but only if they follow you or someone they follow reblogged/replied to your post.
|
||||||
|
|
||||||
The Mastodon documentation has some more information about [Unlisted posting](https://docs.joinmastodon.org/user/posting/#unlisted) and [Public timelines](https://docs.joinmastodon.org/user/network/#timelines).
|
The Mastodon documentation has some more information about [Unlisted posting](https://docs.joinmastodon.org/user/posting/#unlisted) and [Public timelines](https://docs.joinmastodon.org/user/network/#timelines).
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ There's also a handful of custom strings exclusive to this projects that would n
|
|||||||
* [Implement a bookmark button and list](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/bookmarks) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/22))
|
* [Implement a bookmark button and list](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/bookmarks) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/22))
|
||||||
* [Add “Check for update” button in addition to integrated update checker](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/check-for-update-button)
|
* [Add “Check for update” button in addition to integrated update checker](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/check-for-update-button)
|
||||||
* [Add “Mark media as sensitive” option](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/mark-media-as-sensitive)
|
* [Add “Mark media as sensitive” option](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/mark-media-as-sensitive)
|
||||||
* [Add settings to hide replies and reposts from the timeline](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/filter-home-timeline) ([Pull request](https://github.com/mastodon/mastodon-android/pull/317))
|
* [Add settings to hide replies and reblogs from the timeline](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/filter-home-timeline) ([Pull request](https://github.com/mastodon/mastodon-android/pull/317))
|
||||||
* [Follow and unfollow hashtags](https://github.com/sk22/megalodon/commit/7d38f031f197aa6cefaf53e39d929538689c1e4e) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/233))
|
* [Follow and unfollow hashtags](https://github.com/sk22/megalodon/commit/7d38f031f197aa6cefaf53e39d929538689c1e4e) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/233))
|
||||||
* [Notification bell for posts](https://github.com/sk22/megalodon/commit/b166ca705eb9169025ef32bbe6315b42491b57ea) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/81))
|
* [Notification bell for posts](https://github.com/sk22/megalodon/commit/b166ca705eb9169025ef32bbe6315b42491b57ea) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/81))
|
||||||
* [Viewing lists and adding/removing users from lists](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:list-timeline-views) based on [@obstsalatschuessel](https://github.com/obstsalatschuessel)'s [Pull request](https://github.com/mastodon/mastodon-android/pull/286)
|
* [Viewing lists and adding/removing users from lists](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:list-timeline-views) based on [@obstsalatschuessel](https://github.com/obstsalatschuessel)'s [Pull request](https://github.com/mastodon/mastodon-android/pull/286)
|
||||||
@@ -133,6 +133,7 @@ There's also a handful of custom strings exclusive to this projects that would n
|
|||||||
* [Add translate function](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/translate-button)
|
* [Add translate function](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/translate-button)
|
||||||
* [Add language selector](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/language-selector)
|
* [Add language selector](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/language-selector)
|
||||||
* [Implement deleting notifications](https://github.com/sk22/megalodon/commit/b0f9ce081f69f29ad59658fc00ca41372cd2677d) (disabled by default)
|
* [Implement deleting notifications](https://github.com/sk22/megalodon/commit/b0f9ce081f69f29ad59658fc00ca41372cd2677d) (disabled by default)
|
||||||
|
* [Long-click boost button to "quote" a post](https://github.com/sk22/megalodon/commit/b25a237c20c6a924ed4d9b357999867c3a32b32b)
|
||||||
|
|
||||||
|
|
||||||
### Behavior
|
### Behavior
|
||||||
@@ -153,8 +154,8 @@ There's also a handful of custom strings exclusive to this projects that would n
|
|||||||
* [Copy post URL when long-pressing share button](https://github.com/sk22/megalodon/commit/ba36347f03278763ecec617b1ce57ba89db7be72)
|
* [Copy post URL when long-pressing share button](https://github.com/sk22/megalodon/commit/ba36347f03278763ecec617b1ce57ba89db7be72)
|
||||||
* [Add option to disable swiping between tabs](https://github.com/sk22/megalodon/commit/1f20b21fc84bf006c1ec14bd2229cbfad5215ec8)
|
* [Add option to disable swiping between tabs](https://github.com/sk22/megalodon/commit/1f20b21fc84bf006c1ec14bd2229cbfad5215ec8)
|
||||||
* [Resolve Fediverse links in the app](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/open-urls-in-app)
|
* [Resolve Fediverse links in the app](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/open-urls-in-app)
|
||||||
* [Long-click boost button to "quote" a post](https://github.com/sk22/megalodon/commit/b25a237c20c6a924ed4d9b357999867c3a32b32b)
|
|
||||||
* [Preserve whitespaces in HTML](https://github.com/sk22/megalodon/commit/7d876bddc7a07d98f0fecbf62b13bdb9fcce3412)
|
* [Preserve whitespaces in HTML](https://github.com/sk22/megalodon/commit/7d876bddc7a07d98f0fecbf62b13bdb9fcce3412)
|
||||||
|
* [Long-click to copy links](https://github.com/sk22/megalodon/commit/b32e32274923a94742a9926ef38785f746d41405)
|
||||||
|
|
||||||
|
|
||||||
### Visual
|
### Visual
|
||||||
|
|||||||
3
fix-metadata-markdown-lists.sh
Executable file
3
fix-metadata-markdown-lists.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
find metadata -name '*.txt' -exec sed -Ei 's/^[–—─•·*]\s+/- /' {} \;
|
||||||
@@ -9,8 +9,8 @@ android {
|
|||||||
applicationId "org.joinmastodon.android.sk"
|
applicationId "org.joinmastodon.android.sk"
|
||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 62
|
versionCode 63
|
||||||
versionName "1.1.5+fork.62"
|
versionName "1.1.5+fork.63"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
resConfigs "ar-rSA", "be-rBY", "bn-rBD", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES", "eu-rES", "fi-rFI", "fil-rPH", "fr-rFR", "ga-rIE", "gd-rGB", "gl-rES", "hi-rIN", "hr-rHR", "hu-rHU", "hy-rAM", "in-rID", "is-rIS", "it-rIT", "iw-rIL", "ja-rJP", "kab", "ko-rKR", "nl-rNL", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ro-rRO", "ru-rRU", "si-rLK", "sl-rSI", "sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW"
|
resConfigs "ar-rSA", "be-rBY", "bn-rBD", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES", "eu-rES", "fi-rFI", "fil-rPH", "fr-rFR", "ga-rIE", "gd-rGB", "gl-rES", "hi-rIN", "hr-rHR", "hu-rHU", "hy-rAM", "in-rID", "is-rIS", "it-rIT", "iw-rIL", "ja-rJP", "kab", "ko-rKR", "nl-rNL", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ro-rRO", "ru-rRU", "si-rLK", "sl-rSI", "sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited;
|
|||||||
import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged;
|
||||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -59,7 +60,7 @@ public class StatusInteractionController{
|
|||||||
E.post(new StatusCountersUpdatedEvent(status));
|
E.post(new StatusCountersUpdatedEvent(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReblogged(Status status, boolean reblogged, Consumer<Status> cb){
|
public void setReblogged(Status status, boolean reblogged, StatusPrivacy visibility, Consumer<Status> cb){
|
||||||
if(!Looper.getMainLooper().isCurrentThread())
|
if(!Looper.getMainLooper().isCurrentThread())
|
||||||
throw new IllegalStateException("Can only be called from main thread");
|
throw new IllegalStateException("Can only be called from main thread");
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ public class StatusInteractionController{
|
|||||||
if(current!=null){
|
if(current!=null){
|
||||||
current.cancel();
|
current.cancel();
|
||||||
}
|
}
|
||||||
SetStatusReblogged req=(SetStatusReblogged) new SetStatusReblogged(status.id, reblogged)
|
SetStatusReblogged req=(SetStatusReblogged) new SetStatusReblogged(status.id, reblogged, visibility)
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Status reblog){
|
public void onSuccess(Status reblog){
|
||||||
|
|||||||
@@ -2,10 +2,17 @@ package org.joinmastodon.android.api.requests.statuses;
|
|||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
|
|
||||||
public class SetStatusReblogged extends MastodonAPIRequest<Status>{
|
public class SetStatusReblogged extends MastodonAPIRequest<Status>{
|
||||||
public SetStatusReblogged(String id, boolean reblogged){
|
public SetStatusReblogged(String id, boolean reblogged, StatusPrivacy visibility){
|
||||||
super(HttpMethod.POST, "/statuses/"+id+"/"+(reblogged ? "reblog" : "unreblog"), Status.class);
|
super(HttpMethod.POST, "/statuses/"+id+"/"+(reblogged ? "reblog" : "unreblog"), Status.class);
|
||||||
setRequestBody(new Object());
|
Request req = new Request();
|
||||||
|
req.visibility = visibility;
|
||||||
|
setRequestBody(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Request {
|
||||||
|
public StatusPrivacy visibility;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.joinmastodon.android.api.requests.tags;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
|
import org.joinmastodon.android.model.Hashtag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GetFollowedHashtags extends HeaderPaginationRequest<Hashtag> {
|
||||||
|
public GetFollowedHashtags(String maxID, String minID, int limit, String sinceID){
|
||||||
|
super(HttpMethod.GET, "/followed_tags", new TypeToken<>(){});
|
||||||
|
if(maxID!=null)
|
||||||
|
addQueryParameter("max_id", maxID);
|
||||||
|
if(minID!=null)
|
||||||
|
addQueryParameter("min_id", minID);
|
||||||
|
if(sinceID!=null)
|
||||||
|
addQueryParameter("since_id", sinceID);
|
||||||
|
if(limit>0)
|
||||||
|
addQueryParameter("limit", ""+limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -13,8 +13,6 @@ import android.net.Uri;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.BuildConfig;
|
import org.joinmastodon.android.BuildConfig;
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
import org.joinmastodon.android.MainActivity;
|
import org.joinmastodon.android.MainActivity;
|
||||||
@@ -104,12 +102,11 @@ public class AccountSessionManager{
|
|||||||
|
|
||||||
public void addAccount(Instance instance, Token token, Account self, Application app, AccountActivationInfo activationInfo){
|
public void addAccount(Instance instance, Token token, Account self, Application app, AccountActivationInfo activationInfo){
|
||||||
instances.put(instance.uri, instance);
|
instances.put(instance.uri, instance);
|
||||||
updateInstanceInfoV2(instance);
|
|
||||||
AccountSession session=new AccountSession(token, self, app, instance.uri, activationInfo==null, activationInfo);
|
AccountSession session=new AccountSession(token, self, app, instance.uri, activationInfo==null, activationInfo);
|
||||||
sessions.put(session.getID(), session);
|
sessions.put(session.getID(), session);
|
||||||
lastActiveAccountID=session.getID();
|
lastActiveAccountID=session.getID();
|
||||||
writeAccountsFile();
|
writeAccountsFile();
|
||||||
updateInstanceEmojis(instance, instance.uri);
|
updateMoreInstanceInfo(instance, instance.uri);
|
||||||
if(PushSubscriptionManager.arePushNotificationsAvailable()){
|
if(PushSubscriptionManager.arePushNotificationsAvailable()){
|
||||||
session.getPushSubscriptionManager().registerAccountForPush(null);
|
session.getPushSubscriptionManager().registerAccountForPush(null);
|
||||||
}
|
}
|
||||||
@@ -328,10 +325,7 @@ public class AccountSessionManager{
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(Instance instance){
|
public void onSuccess(Instance instance){
|
||||||
instances.put(domain, instance);
|
instances.put(domain, instance);
|
||||||
updateInstanceEmojis(instance, domain);
|
updateMoreInstanceInfo(instance, domain);
|
||||||
try {
|
|
||||||
updateInstanceInfoV2(instance);
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -342,16 +336,18 @@ public class AccountSessionManager{
|
|||||||
.execNoAuth(domain);
|
.execNoAuth(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateInstanceInfoV2(Instance instance) {
|
public void updateMoreInstanceInfo(Instance instance, String domain) {
|
||||||
new GetInstance.V2().setCallback(new Callback<>() {
|
new GetInstance.V2().setCallback(new Callback<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Instance.V2 v2) {
|
public void onSuccess(Instance.V2 v2) {
|
||||||
if (instance != null) instance.v2 = v2;
|
if (instance != null) instance.v2 = v2;
|
||||||
writeAccountsFile();
|
updateInstanceEmojis(instance, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(ErrorResponse errorResponse) {}
|
public void onError(ErrorResponse errorResponse) {
|
||||||
|
updateInstanceEmojis(instance, domain);
|
||||||
|
}
|
||||||
}).execNoAuth(instance.uri);
|
}).execNoAuth(instance.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -638,6 +638,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
} else {
|
} else {
|
||||||
publishButton.setText(publishText);
|
publishButton.setText(publishText);
|
||||||
}
|
}
|
||||||
|
publishButton.setSingleLine();
|
||||||
|
publishButton.setEllipsize(TextUtils.TruncateAt.END);
|
||||||
publishButton.setOnClickListener(this::onPublishClick);
|
publishButton.setOnClickListener(this::onPublishClick);
|
||||||
LinearLayout wrap=new LinearLayout(getActivity());
|
LinearLayout wrap=new LinearLayout(getActivity());
|
||||||
wrap.setOrientation(LinearLayout.HORIZONTAL);
|
wrap.setOrientation(LinearLayout.HORIZONTAL);
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.requests.tags.GetFollowedHashtags;
|
||||||
|
import org.joinmastodon.android.model.Hashtag;
|
||||||
|
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
|
import me.grishka.appkit.api.SimpleCallback;
|
||||||
|
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||||
|
import me.grishka.appkit.utils.BindableViewHolder;
|
||||||
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
|
public class FollowedHashtagsFragment extends BaseRecyclerFragment<Hashtag> implements ScrollableToTop {
|
||||||
|
private String nextMaxID;
|
||||||
|
private String accountId;
|
||||||
|
|
||||||
|
public FollowedHashtagsFragment() {
|
||||||
|
super(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
Bundle args=getArguments();
|
||||||
|
accountId=args.getString("account");
|
||||||
|
setTitle(R.string.sk_hashtags_you_follow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onShown(){
|
||||||
|
super.onShown();
|
||||||
|
if(!getArguments().getBoolean("noAutoLoad") && !loaded && !dataLoading)
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLoadData(int offset, int count){
|
||||||
|
currentRequest=new GetFollowedHashtags(offset==0 ? null : nextMaxID, null, count, null)
|
||||||
|
.setCallback(new SimpleCallback<>(this){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(HeaderPaginationList<Hashtag> result){
|
||||||
|
if(result.nextPageUri!=null)
|
||||||
|
nextMaxID=result.nextPageUri.getQueryParameter("max_id");
|
||||||
|
else
|
||||||
|
nextMaxID=null;
|
||||||
|
onDataLoaded(result, nextMaxID!=null);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.exec(accountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RecyclerView.Adapter getAdapter() {
|
||||||
|
return new HashtagsAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scrollToTop() {
|
||||||
|
smoothScrollRecyclerViewToTop(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HashtagsAdapter extends RecyclerView.Adapter<HashtagViewHolder>{
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public HashtagViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||||
|
return new HashtagViewHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull HashtagViewHolder holder, int position) {
|
||||||
|
holder.bind(data.get(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return data.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HashtagViewHolder extends BindableViewHolder<Hashtag> implements UsableRecyclerView.Clickable{
|
||||||
|
private final TextView title;
|
||||||
|
|
||||||
|
public HashtagViewHolder(){
|
||||||
|
super(getActivity(), R.layout.item_text, list);
|
||||||
|
title=findViewById(R.id.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBind(Hashtag item) {
|
||||||
|
title.setText(item.name);
|
||||||
|
title.setCompoundDrawablesRelativeWithIntrinsicBounds(itemView.getContext().getDrawable(R.drawable.ic_fluent_number_symbol_24_regular), null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick() {
|
||||||
|
UiUtils.openHashtagTimeline(getActivity(), accountId, item.name, item.following);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
package org.joinmastodon.android.fragments;
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -23,17 +18,13 @@ import org.joinmastodon.android.model.ListTimeline;
|
|||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
|
||||||
import me.grishka.appkit.api.SimpleCallback;
|
import me.grishka.appkit.api.SimpleCallback;
|
||||||
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||||
import me.grishka.appkit.utils.BindableViewHolder;
|
import me.grishka.appkit.utils.BindableViewHolder;
|
||||||
import me.grishka.appkit.utils.V;
|
|
||||||
import me.grishka.appkit.views.UsableRecyclerView;
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> implements ScrollableToTop {
|
public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> implements ScrollableToTop {
|
||||||
@@ -159,7 +150,7 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
|||||||
private final CheckBox listToggle;
|
private final CheckBox listToggle;
|
||||||
|
|
||||||
public ListViewHolder(){
|
public ListViewHolder(){
|
||||||
super(getActivity(), R.layout.item_list_timeline, list);
|
super(getActivity(), R.layout.item_text, list);
|
||||||
title=findViewById(R.id.title);
|
title=findViewById(R.id.title);
|
||||||
listToggle=findViewById(R.id.list_toggle);
|
listToggle=findViewById(R.id.list_toggle);
|
||||||
}
|
}
|
||||||
@@ -167,8 +158,10 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
|||||||
@Override
|
@Override
|
||||||
public void onBind(ListTimeline item) {
|
public void onBind(ListTimeline item) {
|
||||||
title.setText(item.title);
|
title.setText(item.title);
|
||||||
|
title.setCompoundDrawablesRelativeWithIntrinsicBounds(itemView.getContext().getDrawable(R.drawable.ic_fluent_people_community_24_regular), null, null, null);
|
||||||
if (profileAccountId != null) {
|
if (profileAccountId != null) {
|
||||||
Boolean checked = userInList.get(item.id);
|
Boolean checked = userInList.get(item.id);
|
||||||
|
listToggle.setVisibility(View.VISIBLE);
|
||||||
listToggle.setChecked(userInList.containsKey(item.id) && checked != null && checked);
|
listToggle.setChecked(userInList.containsKey(item.id) && checked != null && checked);
|
||||||
listToggle.setOnClickListener(this::onClickToggle);
|
listToggle.setOnClickListener(this::onClickToggle);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -288,11 +288,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
followingBtn.setOnClickListener(this::onFollowersOrFollowingClick);
|
followingBtn.setOnClickListener(this::onFollowersOrFollowingClick);
|
||||||
|
|
||||||
username.setOnLongClickListener(v->{
|
username.setOnLongClickListener(v->{
|
||||||
String username=account.acct;
|
String usernameString=account.acct;
|
||||||
if(!username.contains("@")){
|
if(!usernameString.contains("@")){
|
||||||
username+="@"+AccountSessionManager.getInstance().getAccount(accountID).domain;
|
usernameString+="@"+AccountSessionManager.getInstance().getAccount(accountID).domain;
|
||||||
}
|
}
|
||||||
UiUtils.copyText(getActivity(), '@'+username);
|
UiUtils.copyText(username, '@'+usernameString);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -624,6 +624,10 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
args.putString("profileAccount", profileAccountID);
|
args.putString("profileAccount", profileAccountID);
|
||||||
args.putString("profileDisplayUsername", account.getDisplayUsername());
|
args.putString("profileDisplayUsername", account.getDisplayUsername());
|
||||||
Nav.go(getActivity(), ListTimelinesFragment.class, args);
|
Nav.go(getActivity(), ListTimelinesFragment.class, args);
|
||||||
|
}else if(id==R.id.followed_hashtags){
|
||||||
|
Bundle args=new Bundle();
|
||||||
|
args.putString("account", accountID);
|
||||||
|
Nav.go(getActivity(), FollowedHashtagsFragment.class, args);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
items.add(new TextItem(R.string.sk_settings_filters, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/filters"), R.drawable.ic_fluent_open_24_regular));
|
items.add(new TextItem(R.string.sk_settings_filters, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/filters"), R.drawable.ic_fluent_open_24_regular));
|
||||||
items.add(new TextItem(R.string.sk_settings_auth, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit"), R.drawable.ic_fluent_open_24_regular));
|
items.add(new TextItem(R.string.sk_settings_auth, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit"), R.drawable.ic_fluent_open_24_regular));
|
||||||
|
|
||||||
String instanceName = instance != null && !instance.title.isBlank() ? instance.title : session.domain;
|
String instanceName = UiUtils.getInstanceName(accountID);
|
||||||
items.add(new HeaderItem(instanceName));
|
items.add(new HeaderItem(instanceName));
|
||||||
items.add(new TextItem(R.string.sk_settings_rules, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/about"), R.drawable.ic_fluent_open_24_regular));
|
items.add(new TextItem(R.string.sk_settings_rules, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/about"), R.drawable.ic_fluent_open_24_regular));
|
||||||
items.add(new TextItem(R.string.settings_tos, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms"), R.drawable.ic_fluent_open_24_regular));
|
items.add(new TextItem(R.string.settings_tos, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms"), R.drawable.ic_fluent_open_24_regular));
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
|||||||
action=getString(R.string.edit_multiple_changed);
|
action=getString(R.string.edit_multiple_changed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" · "+date, Collections.emptyList(), 0, null));
|
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" · "+date, Collections.emptyList(), 0, null, null));
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class M3AlertDialogBuilder extends AlertDialog.Builder{
|
|||||||
View title=alert.findViewById(titleID);
|
View title=alert.findViewById(titleID);
|
||||||
if(title!=null){
|
if(title!=null){
|
||||||
int pad=V.dp(24);
|
int pad=V.dp(24);
|
||||||
title.setPadding(pad, pad, pad, pad);
|
title.setPadding(pad, pad, pad, V.dp(18));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int titleDividerID=getContext().getResources().getIdentifier("titleDividerNoCustom", "id", "android");
|
int titleDividerID=getContext().getResources().getIdentifier("titleDividerNoCustom", "id", "android");
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package org.joinmastodon.android.ui.displayitems;
|
package org.joinmastodon.android.ui.displayitems;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
@@ -12,19 +16,24 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
|||||||
import android.view.animation.AlphaAnimation;
|
import android.view.animation.AlphaAnimation;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.model.StatusPrivacy;
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
@@ -132,21 +141,25 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean onButtonTouch(View v, MotionEvent event){
|
private boolean onButtonTouch(View v, MotionEvent event){
|
||||||
|
boolean disabled = !v.isEnabled() || (v instanceof FrameLayout parentFrame &&
|
||||||
|
parentFrame.getChildCount() > 0 && !parentFrame.getChildAt(0).isEnabled());
|
||||||
int action = event.getAction();
|
int action = event.getAction();
|
||||||
long eventDuration = event.getEventTime() - event.getDownTime();
|
long eventDuration = event.getEventTime() - event.getDownTime();
|
||||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
||||||
touchingView = null;
|
touchingView = null;
|
||||||
v.removeCallbacks(longClickRunnable);
|
v.removeCallbacks(longClickRunnable);
|
||||||
v.animate().scaleX(1).scaleY(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start();
|
v.animate().scaleX(1).scaleY(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start();
|
||||||
if (action == MotionEvent.ACTION_UP && eventDuration < ViewConfiguration.getLongPressTimeout()) v.performClick();
|
if (disabled) return true;
|
||||||
|
if (action == MotionEvent.ACTION_UP && eventDuration <= ViewConfiguration.getLongPressTimeout()) v.performClick();
|
||||||
else v.startAnimation(opacityIn);
|
else v.startAnimation(opacityIn);
|
||||||
} else if (action == MotionEvent.ACTION_DOWN) {
|
} else if (action == MotionEvent.ACTION_DOWN) {
|
||||||
touchingView = v;
|
touchingView = v;
|
||||||
// 20dp to center in middle of icon, because: (icon width = 24dp) / 2 + (paddingStart = 8dp)
|
// 20dp to center in middle of icon, because: (icon width = 24dp) / 2 + (paddingStart = 8dp)
|
||||||
v.setPivotX(V.dp(20));
|
v.setPivotX(V.dp(20));
|
||||||
|
v.animate().scaleX(0.85f).scaleY(0.85f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(75).start();
|
||||||
|
if (disabled) return true;
|
||||||
v.postDelayed(longClickRunnable, ViewConfiguration.getLongPressTimeout());
|
v.postDelayed(longClickRunnable, ViewConfiguration.getLongPressTimeout());
|
||||||
v.startAnimation(opacityOut);
|
v.startAnimation(opacityOut);
|
||||||
v.animate().scaleX(0.85f).scaleY(0.85f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(75).start();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -161,21 +174,78 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
|
|
||||||
private void onBoostClick(View v){
|
private void onBoostClick(View v){
|
||||||
boost.setSelected(!item.status.reblogged);
|
boost.setSelected(!item.status.reblogged);
|
||||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setReblogged(item.status, !item.status.reblogged, r->{
|
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setReblogged(item.status, !item.status.reblogged, null, r->boostConsumer(v, r));
|
||||||
v.startAnimation(opacityIn);
|
}
|
||||||
bindButton(boost, r.reblogsCount);
|
|
||||||
});
|
private void boostConsumer(View v, Status r) {
|
||||||
|
v.startAnimation(opacityIn);
|
||||||
|
bindButton(boost, r.reblogsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean onBoostLongClick(View v){
|
private boolean onBoostLongClick(View v){
|
||||||
v.setAlpha(1);
|
Context ctx = itemView.getContext();
|
||||||
v.setScaleX(1);
|
View menu = LayoutInflater.from(ctx).inflate(R.layout.item_boost_menu, null);
|
||||||
v.setScaleY(1);
|
Dialog dialog = new M3AlertDialogBuilder(ctx).setView(menu).create();
|
||||||
Bundle args=new Bundle();
|
AccountSession session = AccountSessionManager.getInstance().getAccount(item.accountID);
|
||||||
args.putString("account", item.accountID);
|
|
||||||
args.putString("prefilledText", "\n\n" + item.status.url);
|
Consumer<StatusPrivacy> doReblog = (visibility) -> {
|
||||||
args.putInt("selectionStart", 0);
|
v.startAnimation(opacityOut);
|
||||||
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
session.getStatusInteractionController()
|
||||||
|
.setReblogged(item.status, !item.status.reblogged, visibility, r->boostConsumer(v, r));
|
||||||
|
dialog.dismiss();
|
||||||
|
};
|
||||||
|
|
||||||
|
View separator = menu.findViewById(R.id.separator);
|
||||||
|
TextView reblogHeader = menu.findViewById(R.id.reblog_header);
|
||||||
|
TextView undoReblog = menu.findViewById(R.id.delete_reblog);
|
||||||
|
TextView itemPublic = menu.findViewById(R.id.vis_public);
|
||||||
|
TextView itemUnlisted = menu.findViewById(R.id.vis_unlisted);
|
||||||
|
TextView itemFollowers = menu.findViewById(R.id.vis_followers);
|
||||||
|
|
||||||
|
undoReblog.setVisibility(item.status.reblogged ? View.VISIBLE : View.GONE);
|
||||||
|
separator.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||||
|
reblogHeader.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
itemPublic.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.PUBLIC) ? View.GONE : View.VISIBLE);
|
||||||
|
itemUnlisted.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.UNLISTED) ? View.GONE : View.VISIBLE);
|
||||||
|
itemFollowers.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.PRIVATE) ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
Drawable checkMark = ctx.getDrawable(R.drawable.ic_fluent_checkmark_circle_20_regular);
|
||||||
|
Drawable publicDrawable = ctx.getDrawable(R.drawable.ic_fluent_earth_24_regular);
|
||||||
|
Drawable unlistedDrawable = ctx.getDrawable(R.drawable.ic_fluent_people_community_24_regular);
|
||||||
|
Drawable followersDrawable = ctx.getDrawable(R.drawable.ic_fluent_people_checkmark_24_regular);
|
||||||
|
|
||||||
|
StatusPrivacy defaultVisibility = session.preferences.postingDefaultVisibility;
|
||||||
|
// e.g. post visibility is unlisted, but default is public
|
||||||
|
// in this case, we want to display the check mark on the most visible visibility
|
||||||
|
if (item.status.visibility.isLessVisibleThan(defaultVisibility)) {
|
||||||
|
for (StatusPrivacy vis : StatusPrivacy.values()) {
|
||||||
|
if (vis.equals(item.status.visibility)) {
|
||||||
|
defaultVisibility = vis;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itemPublic.setCompoundDrawablesWithIntrinsicBounds(publicDrawable, null, StatusPrivacy.PUBLIC.equals(defaultVisibility) ? checkMark : null, null);
|
||||||
|
itemUnlisted.setCompoundDrawablesWithIntrinsicBounds(unlistedDrawable, null, StatusPrivacy.UNLISTED.equals(defaultVisibility) ? checkMark : null, null);
|
||||||
|
itemFollowers.setCompoundDrawablesWithIntrinsicBounds(followersDrawable, null, StatusPrivacy.PRIVATE.equals(defaultVisibility) ? checkMark : null, null);
|
||||||
|
|
||||||
|
undoReblog.setOnClickListener(c->doReblog.accept(null));
|
||||||
|
itemPublic.setOnClickListener(c->doReblog.accept(StatusPrivacy.PUBLIC));
|
||||||
|
itemUnlisted.setOnClickListener(c->doReblog.accept(StatusPrivacy.UNLISTED));
|
||||||
|
itemFollowers.setOnClickListener(c->doReblog.accept(StatusPrivacy.PRIVATE));
|
||||||
|
|
||||||
|
menu.findViewById(R.id.quote).setOnClickListener(c->{
|
||||||
|
dialog.dismiss();
|
||||||
|
v.startAnimation(opacityIn);
|
||||||
|
Bundle args=new Bundle();
|
||||||
|
args.putString("account", item.accountID);
|
||||||
|
args.putString("prefilledText", "\n\n" + item.status.url);
|
||||||
|
args.putInt("selectionStart", 0);
|
||||||
|
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +273,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean onShareLongClick(View v){
|
private boolean onShareLongClick(View v){
|
||||||
UiUtils.copyText(v.getContext(), item.status.url);
|
UiUtils.copyText(v, item.status.url);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import android.text.SpannableStringBuilder;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.SubMenu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewOutlineProvider;
|
import android.view.ViewOutlineProvider;
|
||||||
@@ -19,12 +20,11 @@ import android.widget.PopupMenu;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
@@ -45,6 +45,7 @@ import org.parceler.Parcels;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.APIRequest;
|
import me.grishka.appkit.api.APIRequest;
|
||||||
@@ -139,6 +140,12 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
avatar.setOutlineProvider(roundCornersOutline);
|
avatar.setOutlineProvider(roundCornersOutline);
|
||||||
avatar.setClipToOutline(true);
|
avatar.setClipToOutline(true);
|
||||||
more.setOnClickListener(this::onMoreClick);
|
more.setOnClickListener(this::onMoreClick);
|
||||||
|
more.setOnLongClickListener((v) -> {
|
||||||
|
PopupMenu popup = new PopupMenu(itemView.getContext(), v);
|
||||||
|
populateAccountsMenu(popup.getMenu());
|
||||||
|
popup.show();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
visibility.setOnClickListener(v->item.parentFragment.onVisibilityIconClick(this));
|
visibility.setOnClickListener(v->item.parentFragment.onVisibilityIconClick(this));
|
||||||
deleteNotification.setOnClickListener(v->UiUtils.confirmDeleteNotification(activity, item.parentFragment.getAccountID(), item.notification, ()->{
|
deleteNotification.setOnClickListener(v->UiUtils.confirmDeleteNotification(activity, item.parentFragment.getAccountID(), item.notification, ()->{
|
||||||
if (item.parentFragment instanceof NotificationsListFragment fragment) {
|
if (item.parentFragment instanceof NotificationsListFragment fragment) {
|
||||||
@@ -151,6 +158,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
optionsMenu.setOnMenuItemClickListener(menuItem->{
|
optionsMenu.setOnMenuItemClickListener(menuItem->{
|
||||||
Account account=item.user;
|
Account account=item.user;
|
||||||
int id=menuItem.getItemId();
|
int id=menuItem.getItemId();
|
||||||
|
|
||||||
|
SubMenu accountsMenu=id==R.id.open_with_account ? menuItem.getSubMenu() : null;
|
||||||
|
if (accountsMenu != null) {
|
||||||
|
accountsMenu.clear();
|
||||||
|
populateAccountsMenu(accountsMenu);
|
||||||
|
}
|
||||||
|
|
||||||
if(id==R.id.edit || id==R.id.delete_and_redraft) {
|
if(id==R.id.edit || id==R.id.delete_and_redraft) {
|
||||||
final Bundle args=new Bundle();
|
final Bundle args=new Bundle();
|
||||||
args.putString("account", item.parentFragment.getAccountID());
|
args.putString("account", item.parentFragment.getAccountID());
|
||||||
@@ -191,20 +205,19 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
}else if(id==R.id.delete){
|
}else if(id==R.id.delete){
|
||||||
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
||||||
}else if(id==R.id.pin || id==R.id.unpin){
|
}else if(id==R.id.pin || id==R.id.unpin) {
|
||||||
UiUtils.confirmPinPost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, !item.status.pinned, s->{});
|
UiUtils.confirmPinPost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, !item.status.pinned, s -> {
|
||||||
}else if(id==R.id.mute){
|
});
|
||||||
UiUtils.confirmToggleMuteUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, relationship!=null && relationship.muting, r->{});
|
|
||||||
}else if(id==R.id.block){
|
|
||||||
UiUtils.confirmToggleBlockUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, relationship!=null && relationship.blocking, r->{});
|
|
||||||
}else if(id==R.id.report){
|
}else if(id==R.id.report){
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", item.parentFragment.getAccountID());
|
args.putString("account", item.parentFragment.getAccountID());
|
||||||
args.putParcelable("status", Parcels.wrap(item.status));
|
args.putParcelable("status", Parcels.wrap(item.status));
|
||||||
args.putParcelable("reportAccount", Parcels.wrap(item.status.account));
|
args.putParcelable("reportAccount", Parcels.wrap(item.status.account));
|
||||||
Nav.go(item.parentFragment.getActivity(), ReportReasonChoiceFragment.class, args);
|
Nav.go(item.parentFragment.getActivity(), ReportReasonChoiceFragment.class, args);
|
||||||
}else if(id==R.id.open_in_browser){
|
}else if(id==R.id.open_in_browser) {
|
||||||
UiUtils.launchWebBrowser(activity, item.status.url);
|
UiUtils.launchWebBrowser(activity, item.status.url);
|
||||||
|
}else if(id==R.id.copy_link){
|
||||||
|
UiUtils.copyText(parent, item.status.url);
|
||||||
}else if(id==R.id.follow){
|
}else if(id==R.id.follow){
|
||||||
if(relationship==null)
|
if(relationship==null)
|
||||||
return true;
|
return true;
|
||||||
@@ -229,6 +242,17 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void populateAccountsMenu(Menu menu) {
|
||||||
|
List<AccountSession> sessions=AccountSessionManager.getInstance().getLoggedInAccounts();
|
||||||
|
sessions.stream().filter(s -> !s.getID().equals(item.accountID)).forEach(s -> {
|
||||||
|
String username = "@"+s.self.username+"@"+s.domain;
|
||||||
|
menu.add(username).setOnMenuItemClickListener(c->{
|
||||||
|
UiUtils.openURL(item.parentFragment.getActivity(), s.getID(), item.status.url, false);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(HeaderStatusDisplayItem item){
|
public void onBind(HeaderStatusDisplayItem item){
|
||||||
name.setText(item.parsedName);
|
name.setText(item.parsedName);
|
||||||
@@ -320,6 +344,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
menu.findItem(R.id.pin).setVisible(item.status!=null && isOwnPost && !item.status.pinned);
|
menu.findItem(R.id.pin).setVisible(item.status!=null && isOwnPost && !item.status.pinned);
|
||||||
menu.findItem(R.id.unpin).setVisible(item.status!=null && isOwnPost && item.status.pinned);
|
menu.findItem(R.id.unpin).setVisible(item.status!=null && isOwnPost && item.status.pinned);
|
||||||
menu.findItem(R.id.open_in_browser).setVisible(item.status!=null);
|
menu.findItem(R.id.open_in_browser).setVisible(item.status!=null);
|
||||||
|
menu.findItem(R.id.copy_link).setVisible(item.status!=null);
|
||||||
MenuItem blockDomain=menu.findItem(R.id.block_domain);
|
MenuItem blockDomain=menu.findItem(R.id.block_domain);
|
||||||
MenuItem mute=menu.findItem(R.id.mute);
|
MenuItem mute=menu.findItem(R.id.mute);
|
||||||
MenuItem block=menu.findItem(R.id.block);
|
MenuItem block=menu.findItem(R.id.block);
|
||||||
@@ -349,12 +374,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
mute.setTitle(item.parentFragment.getString(relationship!=null && relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
mute.setTitle(item.parentFragment.getString(relationship!=null && relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||||
block.setTitle(item.parentFragment.getString(relationship!=null && relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
block.setTitle(item.parentFragment.getString(relationship!=null && relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||||
report.setTitle(item.parentFragment.getString(R.string.report_user, account.getDisplayUsername()));
|
report.setTitle(item.parentFragment.getString(R.string.report_user, account.getDisplayUsername()));
|
||||||
if(!account.isLocal()){
|
// disabled in megalodon. domain blocks from a post clutters the context menu and looks out of place
|
||||||
blockDomain.setVisible(true);
|
// if(!account.isLocal()){
|
||||||
blockDomain.setTitle(item.parentFragment.getString(relationship!=null && relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
// blockDomain.setVisible(true);
|
||||||
}else{
|
// blockDomain.setTitle(item.parentFragment.getString(relationship!=null && relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
||||||
|
// }else{
|
||||||
blockDomain.setVisible(false);
|
blockDomain.setVisible(false);
|
||||||
}
|
// }
|
||||||
follow.setTitle(item.parentFragment.getString(relationship!=null && relationship.following ? R.string.unfollow_user : R.string.follow_user, account.getDisplayUsername()));
|
follow.setTitle(item.parentFragment.getString(relationship!=null && relationship.following ? R.string.unfollow_user : R.string.follow_user, account.getDisplayUsername()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class LinkCardStatusDisplayItem extends StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onClick(View v){
|
private void onClick(View v){
|
||||||
UiUtils.launchWebBrowser(itemView.getContext(), item.status.card.url);
|
UiUtils.openURL(itemView.getContext(), item.parentFragment.getAccountID(), item.status.card.url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.joinmastodon.android.ui.displayitems;
|
|||||||
import static org.joinmastodon.android.MastodonApp.context;
|
import static org.joinmastodon.android.MastodonApp.context;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
@@ -14,6 +15,7 @@ import android.widget.TextView;
|
|||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.model.Emoji;
|
import org.joinmastodon.android.model.Emoji;
|
||||||
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
@@ -30,10 +32,13 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
|||||||
private CharSequence text;
|
private CharSequence text;
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
private int icon;
|
private int icon;
|
||||||
|
private StatusPrivacy visibility;
|
||||||
|
@DrawableRes
|
||||||
|
private int iconEnd;
|
||||||
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
|
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
|
||||||
private View.OnClickListener handleClick;
|
private View.OnClickListener handleClick;
|
||||||
|
|
||||||
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, @Nullable View.OnClickListener handleClick){
|
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, StatusPrivacy visibility, @Nullable View.OnClickListener handleClick){
|
||||||
super(parentID, parentFragment);
|
super(parentID, parentFragment);
|
||||||
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
|
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
|
||||||
HtmlParser.parseCustomEmoji(ssb, emojis);
|
HtmlParser.parseCustomEmoji(ssb, emojis);
|
||||||
@@ -43,6 +48,17 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
|||||||
this.handleClick=handleClick;
|
this.handleClick=handleClick;
|
||||||
TypedValue outValue = new TypedValue();
|
TypedValue outValue = new TypedValue();
|
||||||
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
|
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
|
||||||
|
updateVisibility(visibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateVisibility(StatusPrivacy visibility) {
|
||||||
|
this.visibility = visibility;
|
||||||
|
this.iconEnd = visibility != null ? switch (visibility) {
|
||||||
|
case PUBLIC -> R.drawable.ic_fluent_earth_20_regular;
|
||||||
|
case UNLISTED -> R.drawable.ic_fluent_people_community_20_regular;
|
||||||
|
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_20_regular;
|
||||||
|
default -> 0;
|
||||||
|
} : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,10 +86,18 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
|||||||
@Override
|
@Override
|
||||||
public void onBind(ReblogOrReplyLineStatusDisplayItem item){
|
public void onBind(ReblogOrReplyLineStatusDisplayItem item){
|
||||||
text.setText(item.text);
|
text.setText(item.text);
|
||||||
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0);
|
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, item.iconEnd, 0);
|
||||||
if(item.handleClick!=null) text.setOnClickListener(item.handleClick);
|
if(item.handleClick!=null) text.setOnClickListener(item.handleClick);
|
||||||
text.setEnabled(!item.inset);
|
text.setEnabled(!item.inset);
|
||||||
text.setClickable(!item.inset);
|
text.setClickable(!item.inset);
|
||||||
|
Context ctx = itemView.getContext();
|
||||||
|
int visibilityText = item.visibility != null ? switch (item.visibility) {
|
||||||
|
case PUBLIC -> R.string.visibility_public;
|
||||||
|
case UNLISTED -> R.string.sk_visibility_unlisted;
|
||||||
|
case PRIVATE -> R.string.visibility_followers_only;
|
||||||
|
default -> 0;
|
||||||
|
} : 0;
|
||||||
|
if (visibilityText != 0) text.setContentDescription(item.text + " (" + ctx.getString(visibilityText) + ")");
|
||||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
||||||
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||||
@@ -81,13 +82,14 @@ public abstract class StatusDisplayItem{
|
|||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
if(status.reblog!=null){
|
if(status.reblog!=null){
|
||||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20_filled, i->{
|
boolean isOwnPost = AccountSessionManager.getInstance().isSelf(fragment.getAccountID(), status.account);
|
||||||
|
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20_filled, isOwnPost ? status.visibility : null, i->{
|
||||||
args.putParcelable("profileAccount", Parcels.wrap(status.account));
|
args.putParcelable("profileAccount", Parcels.wrap(status.account));
|
||||||
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
||||||
}));
|
}));
|
||||||
}else if(status.inReplyToAccountId!=null && knownAccounts.containsKey(status.inReplyToAccountId)){
|
}else if(status.inReplyToAccountId!=null && knownAccounts.containsKey(status.inReplyToAccountId)){
|
||||||
Account account=Objects.requireNonNull(knownAccounts.get(status.inReplyToAccountId));
|
Account account=Objects.requireNonNull(knownAccounts.get(status.inReplyToAccountId));
|
||||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_fluent_arrow_reply_20_filled, i->{
|
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_fluent_arrow_reply_20_filled, null, i->{
|
||||||
args.putParcelable("profileAccount", Parcels.wrap(account));
|
args.putParcelable("profileAccount", Parcels.wrap(account));
|
||||||
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import android.text.Layout;
|
|||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.SoundEffectConstants;
|
import android.view.SoundEffectConstants;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
@@ -20,7 +22,11 @@ public class ClickableLinksDelegate {
|
|||||||
private Path hlPath;
|
private Path hlPath;
|
||||||
private LinkSpan selectedSpan;
|
private LinkSpan selectedSpan;
|
||||||
private TextView view;
|
private TextView view;
|
||||||
|
|
||||||
|
private final Runnable longClickRunnable = () -> {
|
||||||
|
if (selectedSpan != null) selectedSpan.onLongClick(view);
|
||||||
|
};
|
||||||
|
|
||||||
public ClickableLinksDelegate(TextView view) {
|
public ClickableLinksDelegate(TextView view) {
|
||||||
this.view=view;
|
this.view=view;
|
||||||
hlPaint=new Paint();
|
hlPaint=new Paint();
|
||||||
@@ -30,6 +36,7 @@ public class ClickableLinksDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean onTouch(MotionEvent event) {
|
public boolean onTouch(MotionEvent event) {
|
||||||
|
long eventDuration = event.getEventTime() - event.getDownTime();
|
||||||
if(event.getAction()==MotionEvent.ACTION_DOWN){
|
if(event.getAction()==MotionEvent.ACTION_DOWN){
|
||||||
int line=-1;
|
int line=-1;
|
||||||
Rect rect=new Rect();
|
Rect rect=new Rect();
|
||||||
@@ -63,6 +70,7 @@ public class ClickableLinksDelegate {
|
|||||||
}
|
}
|
||||||
hlPath=new Path();
|
hlPath=new Path();
|
||||||
selectedSpan=span;
|
selectedSpan=span;
|
||||||
|
view.postDelayed(longClickRunnable, ViewConfiguration.getLongPressTimeout());
|
||||||
hlPaint.setColor((span.getColor() & 0x00FFFFFF) | 0x33000000);
|
hlPaint.setColor((span.getColor() & 0x00FFFFFF) | 0x33000000);
|
||||||
//l.getSelectionPath(start, end, hlPath);
|
//l.getSelectionPath(start, end, hlPath);
|
||||||
for(int j=lstart;j<=lend;j++){
|
for(int j=lstart;j<=lend;j++){
|
||||||
@@ -90,8 +98,11 @@ public class ClickableLinksDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(event.getAction()==MotionEvent.ACTION_UP && selectedSpan!=null){
|
if(event.getAction()==MotionEvent.ACTION_UP && selectedSpan!=null){
|
||||||
view.playSoundEffect(SoundEffectConstants.CLICK);
|
if (eventDuration <= ViewConfiguration.getLongPressTimeout()) {
|
||||||
selectedSpan.onClick(view.getContext());
|
view.playSoundEffect(SoundEffectConstants.CLICK);
|
||||||
|
selectedSpan.onClick(view.getContext());
|
||||||
|
}
|
||||||
|
view.removeCallbacks(longClickRunnable);
|
||||||
hlPath=null;
|
hlPath=null;
|
||||||
selectedSpan=null;
|
selectedSpan=null;
|
||||||
view.invalidate();
|
view.invalidate();
|
||||||
@@ -100,6 +111,7 @@ public class ClickableLinksDelegate {
|
|||||||
if(event.getAction()==MotionEvent.ACTION_CANCEL){
|
if(event.getAction()==MotionEvent.ACTION_CANCEL){
|
||||||
hlPath=null;
|
hlPath=null;
|
||||||
selectedSpan=null;
|
selectedSpan=null;
|
||||||
|
view.removeCallbacks(longClickRunnable);
|
||||||
view.invalidate();
|
view.invalidate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ public class HtmlParser{
|
|||||||
case "a" -> {
|
case "a" -> {
|
||||||
String href=el.attr("href");
|
String href=el.attr("href");
|
||||||
LinkSpan.Type linkType;
|
LinkSpan.Type linkType;
|
||||||
|
String text=el.text();
|
||||||
if(el.hasClass("hashtag")){
|
if(el.hasClass("hashtag")){
|
||||||
String text=el.text();
|
|
||||||
if(text.startsWith("#")){
|
if(text.startsWith("#")){
|
||||||
linkType=LinkSpan.Type.HASHTAG;
|
linkType=LinkSpan.Type.HASHTAG;
|
||||||
href=text.substring(1);
|
href=text.substring(1);
|
||||||
@@ -136,7 +136,7 @@ public class HtmlParser{
|
|||||||
}else{
|
}else{
|
||||||
linkType=LinkSpan.Type.URL;
|
linkType=LinkSpan.Type.URL;
|
||||||
}
|
}
|
||||||
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID), ssb.length(), el));
|
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID, text), ssb.length(), el));
|
||||||
}
|
}
|
||||||
case "br" -> ssb.append('\n');
|
case "br" -> ssb.append('\n');
|
||||||
case "span" -> {
|
case "span" -> {
|
||||||
@@ -260,7 +260,7 @@ public class HtmlParser{
|
|||||||
String url=matcher.group(3);
|
String url=matcher.group(3);
|
||||||
if(TextUtils.isEmpty(matcher.group(4)))
|
if(TextUtils.isEmpty(matcher.group(4)))
|
||||||
url="http://"+url;
|
url="http://"+url;
|
||||||
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null), matcher.start(3), matcher.end(3), 0);
|
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null, url), matcher.start(3), matcher.end(3), 0);
|
||||||
}while(matcher.find()); // Find more URLs
|
}while(matcher.find()); // Find more URLs
|
||||||
return ssb;
|
return ssb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.joinmastodon.android.ui.text;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.text.style.CharacterStyle;
|
import android.text.style.CharacterStyle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
@@ -13,12 +14,14 @@ public class LinkSpan extends CharacterStyle {
|
|||||||
private String link;
|
private String link;
|
||||||
private Type type;
|
private Type type;
|
||||||
private String accountID;
|
private String accountID;
|
||||||
|
private String text;
|
||||||
|
|
||||||
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID){
|
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID, String text){
|
||||||
this.listener=listener;
|
this.listener=listener;
|
||||||
this.link=link;
|
this.link=link;
|
||||||
this.type=type;
|
this.type=type;
|
||||||
this.accountID=accountID;
|
this.accountID=accountID;
|
||||||
|
this.text=text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColor(){
|
public int getColor(){
|
||||||
@@ -38,6 +41,10 @@ public class LinkSpan extends CharacterStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onLongClick(View view) {
|
||||||
|
UiUtils.copyText(view, getType() == Type.URL ? link : text);
|
||||||
|
}
|
||||||
|
|
||||||
public String getLink(){
|
public String getLink(){
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.provider.OpenableColumns;
|
|||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -56,6 +57,7 @@ import org.joinmastodon.android.api.requests.search.GetSearchResults;
|
|||||||
import org.joinmastodon.android.api.requests.statuses.DeleteStatus;
|
import org.joinmastodon.android.api.requests.statuses.DeleteStatus;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
|
||||||
import org.joinmastodon.android.api.requests.statuses.SetStatusPinned;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusPinned;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||||
import org.joinmastodon.android.events.FollowRequestHandledEvent;
|
import org.joinmastodon.android.events.FollowRequestHandledEvent;
|
||||||
@@ -69,6 +71,7 @@ import org.joinmastodon.android.fragments.ProfileFragment;
|
|||||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.Emoji;
|
import org.joinmastodon.android.model.Emoji;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
import org.joinmastodon.android.model.ListTimeline;
|
import org.joinmastodon.android.model.ListTimeline;
|
||||||
import org.joinmastodon.android.model.Notification;
|
import org.joinmastodon.android.model.Notification;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
@@ -96,6 +99,7 @@ import java.util.function.Consumer;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import androidx.annotation.AttrRes;
|
import androidx.annotation.AttrRes;
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.browser.customtabs.CustomTabsIntent;
|
import androidx.browser.customtabs.CustomTabsIntent;
|
||||||
@@ -731,22 +735,37 @@ public class UiUtils{
|
|||||||
|
|
||||||
String it = uri.getPath();
|
String it = uri.getPath();
|
||||||
return it.matches("^/@[^/]+$") ||
|
return it.matches("^/@[^/]+$") ||
|
||||||
it.matches("^/@[^/]+/\\d+$") ||
|
it.matches("^/@[^/]+/\\d+$") ||
|
||||||
it.matches("^/users/\\w+$") ||
|
it.matches("^/users/\\w+$") ||
|
||||||
it.matches("^/notice/[a-zA-Z0-9]+$") ||
|
it.matches("^/notice/[a-zA-Z0-9]+$") ||
|
||||||
it.matches("^/objects/[-a-f0-9]+$") ||
|
it.matches("^/objects/[-a-f0-9]+$") ||
|
||||||
it.matches("^/notes/[a-z0-9]+$") ||
|
it.matches("^/notes/[a-z0-9]+$") ||
|
||||||
it.matches("^/display/[-a-f0-9]+$") ||
|
it.matches("^/display/[-a-f0-9]+$") ||
|
||||||
it.matches("^/profile/\\w+$") ||
|
it.matches("^/profile/\\w+$") ||
|
||||||
it.matches("^/p/\\w+/\\d+$") ||
|
it.matches("^/p/\\w+/\\d+$") ||
|
||||||
it.matches("^/\\w+$") ||
|
it.matches("^/\\w+$") ||
|
||||||
it.matches("^/@[^/]+/statuses/[a-zA-Z0-9]+$") ||
|
it.matches("^/@[^/]+/statuses/[a-zA-Z0-9]+$") ||
|
||||||
it.matches("^/o/[a-f0-9]+$");
|
it.matches("^/users/[^/]+/statuses/[a-zA-Z0-9]+$") ||
|
||||||
|
it.matches("^/o/[a-f0-9]+$");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openURL(Context context, String accountID, String url){
|
public static String getInstanceName(String accountID) {
|
||||||
|
AccountSession session = AccountSessionManager.getInstance().getAccount(accountID);
|
||||||
|
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
|
||||||
|
return instance != null && !instance.title.isBlank() ? instance.title : session.domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openURL(Context context, String accountID, String url) {
|
||||||
|
openURL(context, accountID, url, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openURL(Context context, String accountID, String url, boolean launchBrowser){
|
||||||
Consumer<ProgressDialog> transformDialogForLookup = dialog -> {
|
Consumer<ProgressDialog> transformDialogForLookup = dialog -> {
|
||||||
dialog.setTitle(R.string.sk_loading_fediverse_resource_title);
|
if (accountID != null) {
|
||||||
|
dialog.setTitle(context.getString(R.string.sk_loading_resource_on_instance_title, getInstanceName(accountID)));
|
||||||
|
} else {
|
||||||
|
dialog.setTitle(R.string.sk_loading_fediverse_resource_title);
|
||||||
|
}
|
||||||
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), (d, which) -> d.cancel());
|
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), (d, which) -> d.cancel());
|
||||||
dialog.setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.open_in_browser), (d, which) -> {
|
dialog.setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.open_in_browser), (d, which) -> {
|
||||||
d.cancel();
|
d.cancel();
|
||||||
@@ -771,7 +790,7 @@ public class UiUtils{
|
|||||||
@Override
|
@Override
|
||||||
public void onError(ErrorResponse error){
|
public void onError(ErrorResponse error){
|
||||||
error.showToast(context);
|
error.showToast(context);
|
||||||
launchWebBrowser(context, url);
|
if (launchBrowser) launchWebBrowser(context, url);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.wrapProgress((Activity)context, R.string.loading, true, transformDialogForLookup)
|
.wrapProgress((Activity)context, R.string.loading, true, transformDialogForLookup)
|
||||||
@@ -791,14 +810,15 @@ public class UiUtils{
|
|||||||
args.putParcelable("profileAccount", Parcels.wrap(results.accounts.get(0)));
|
args.putParcelable("profileAccount", Parcels.wrap(results.accounts.get(0)));
|
||||||
Nav.go((Activity) context, ProfileFragment.class, args);
|
Nav.go((Activity) context, ProfileFragment.class, args);
|
||||||
} else {
|
} else {
|
||||||
launchWebBrowser(context, url);
|
if (launchBrowser) launchWebBrowser(context, url);
|
||||||
|
else Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(ErrorResponse error) {
|
public void onError(ErrorResponse error) {
|
||||||
error.showToast(context);
|
error.showToast(context);
|
||||||
launchWebBrowser(context, url);
|
if (launchBrowser) launchWebBrowser(context, url);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.wrapProgress((Activity)context, R.string.loading, true, transformDialogForLookup)
|
.wrapProgress((Activity)context, R.string.loading, true, transformDialogForLookup)
|
||||||
@@ -809,14 +829,13 @@ public class UiUtils{
|
|||||||
launchWebBrowser(context, url);
|
launchWebBrowser(context, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copyText(Context context, String text) {
|
public static void copyText(View v, String text) {
|
||||||
|
Context context = v.getContext();
|
||||||
context.getSystemService(ClipboardManager.class).setPrimaryClip(ClipData.newPlainText(null, text));
|
context.getSystemService(ClipboardManager.class).setPrimaryClip(ClipData.newPlainText(null, text));
|
||||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.TIRAMISU || UiUtils.isMIUI()){ // Android 13+ SystemUI shows its own thing when you put things into the clipboard
|
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.TIRAMISU || UiUtils.isMIUI()){ // Android 13+ SystemUI shows its own thing when you put things into the clipboard
|
||||||
Toast.makeText(context, R.string.text_copied, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.text_copied, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
v.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) vibrator.vibrate(VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE));
|
|
||||||
else vibrator.vibrate(50);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getSystemProperty(String key){
|
private static String getSystemProperty(String key){
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
|
||||||
|
<path android:pathData="M10 2c4.418 0 8 3.582 8 8s-3.582 8-8 8-8-3.582-8-8 3.582-8 8-8zm0 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm3.358 4.646c0.174 0.174 0.193 0.443 0.058 0.638l-0.058 0.07-4.005 4.004c-0.173 0.174-0.442 0.193-0.637 0.058l-0.07-0.058-2-2c-0.195-0.195-0.195-0.511 0-0.707C6.82 9.478 7.09 9.46 7.284 9.594l0.07 0.057L9 11.298l3.651-3.652c0.196-0.195 0.512-0.195 0.707 0z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||||
|
</vector>
|
||||||
@@ -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="M21.78 3.28c0.293-0.293 0.293-0.767 0-1.06-0.293-0.293-0.768-0.293-1.06 0l-10 10-0.47 1.53 1.53-0.47 10-10zM6.25 3C4.455 3 3 4.455 3 6.25v11.5C3 19.545 4.455 21 6.25 21h11.5c1.795 0 3.25-1.455 3.25-3.25v-8C21 9.336 20.664 9 20.25 9S19.5 9.336 19.5 9.75v8c0 0.966-0.784 1.75-1.75 1.75H6.25c-0.966 0-1.75-0.784-1.75-1.75V6.25c0-0.966 0.784-1.75 1.75-1.75h8C14.664 4.5 15 4.164 15 3.75S14.664 3 14.25 3h-8z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||||
|
</vector>
|
||||||
@@ -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="M10.987 2.89c0.077-0.408-0.19-0.8-0.598-0.877-0.407-0.077-0.799 0.19-0.876 0.598L8.494 7.998 3.75 8C3.335 8 3 8.336 3 8.75 3 9.166 3.336 9.5 3.75 9.5l4.46-0.002-0.946 5L2.75 14.5C2.335 14.5 2 14.836 2 15.25 2 15.665 2.336 16 2.75 16l4.23-0.002-0.967 5.116c-0.077 0.407 0.19 0.8 0.598 0.876 0.407 0.077 0.799-0.19 0.876-0.598l1.02-5.395 5.474-0.002-0.968 5.119c-0.077 0.407 0.19 0.8 0.598 0.876 0.407 0.077 0.799-0.19 0.876-0.598l1.021-5.398 4.742-0.002c0.415 0 0.75-0.336 0.75-0.75 0-0.415-0.336-0.75-0.75-0.75l-4.458 0.002 0.946-5 4.512-0.002c0.415 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75l-4.23 0.002 0.966-5.104c0.077-0.408-0.19-0.8-0.598-0.877-0.407-0.077-0.799 0.19-0.876 0.598l-1.018 5.384-5.474 0.002 0.966-5.107zm-1.25 6.608l5.474-0.003-0.946 5-5.474 0.002 0.946-5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||||
|
</vector>
|
||||||
@@ -6,12 +6,11 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:paddingTop="16dp"
|
android:paddingTop="16dp"
|
||||||
android:paddingBottom="6dp"
|
android:paddingBottom="6dp"
|
||||||
android:background="?android:selectableItemBackground"
|
|
||||||
android:textAppearance="@style/m3_title_small"
|
android:textAppearance="@style/m3_title_small"
|
||||||
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_20_filled"
|
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_20_filled"
|
||||||
android:drawableTint="?android:textColorSecondary"
|
android:drawableTint="?android:textColorSecondary"
|
||||||
|
|||||||
@@ -241,17 +241,14 @@
|
|||||||
android:textAppearance="@style/m3_headline_small"
|
android:textAppearance="@style/m3_headline_small"
|
||||||
tools:text="Eugen" />
|
tools:text="Eugen" />
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/username"
|
android:id="@+id/username"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_below="@id/name"
|
android:layout_below="@id/name"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingTop="4dp"
|
||||||
android:paddingTop="2dp"
|
android:paddingBottom="8dp"
|
||||||
android:paddingBottom="4dp"
|
|
||||||
android:background="?android:selectableItemBackground"
|
|
||||||
android:textAppearance="@style/m3_title_medium"
|
android:textAppearance="@style/m3_title_medium"
|
||||||
android:textColor="?android:textColorSecondary"
|
android:textColor="?android:textColorSecondary"
|
||||||
tools:text="\@Gargron" />
|
tools:text="\@Gargron" />
|
||||||
@@ -262,7 +259,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/username"
|
android:layout_below="@id/username"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:textAppearance="@style/m3_body_large"
|
android:textAppearance="@style/m3_body_large"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
@@ -291,7 +287,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/username"
|
android:layout_below="@id/username"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:textAppearance="@style/m3_body_large"
|
android:textAppearance="@style/m3_body_large"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
|
|||||||
95
mastodon/src/main/res/layout/item_boost_menu.xml
Normal file
95
mastodon/src/main/res/layout/item_boost_menu.xml
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingVertical="12dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/reblog_header"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:textColor="?android:colorAccent"
|
||||||
|
android:accessibilityHeading="true"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:text="@string/sk_reblog_with_visibility" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/delete_reblog"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="36dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
|
android:text="@string/sk_undo_reblog"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_off_24_regular" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vis_public"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="36dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
|
android:text="@string/visibility_public"
|
||||||
|
android:drawableStart="@drawable/ic_fluent_earth_24_regular" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vis_unlisted"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="36dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
|
android:text="@string/sk_visibility_unlisted"
|
||||||
|
android:drawableStart="@drawable/ic_fluent_people_community_24_regular" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vis_followers"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="36dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
|
android:text="@string/visibility_followers_only"
|
||||||
|
android:drawableStart="@drawable/ic_fluent_people_checkmark_24_regular" />
|
||||||
|
<View
|
||||||
|
android:id="@+id/separator"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginVertical="8dp"
|
||||||
|
android:background="?colorPollVoted" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/quote"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="36dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
|
android:text="@string/sk_quote_post"
|
||||||
|
android:drawableStart="@drawable/ic_fluent_compose_24_regular" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="wrap_content"
|
||||||
android:paddingHorizontal="16dp"
|
android:minHeight="48dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:layoutDirection="locale">
|
android:layoutDirection="locale">
|
||||||
|
|
||||||
@@ -13,6 +12,7 @@
|
|||||||
android:id="@+id/icon"
|
android:id="@+id/icon"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="32dp"
|
android:layout_marginEnd="32dp"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:tint="?android:textColorPrimary"
|
android:tint="?android:textColorPrimary"
|
||||||
@@ -21,10 +21,11 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
android:paddingVertical="8dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:textColor="?android:textColorPrimary"
|
android:textColor="?android:textColorPrimary"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
@@ -33,6 +34,9 @@
|
|||||||
android:id="@+id/button"
|
android:id="@+id/button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:maxWidth="140dp"
|
||||||
android:background="@drawable/bg_inline_button"
|
android:background="@drawable/bg_inline_button"
|
||||||
android:elevation="0dp"
|
android:elevation="0dp"
|
||||||
android:ellipsize="middle"
|
android:ellipsize="middle"
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="48dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:layoutDirection="locale">
|
android:layoutDirection="locale">
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:paddingVertical="8dp"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textColor="?android:textColorPrimary"
|
android:textColor="?android:textColorPrimary"
|
||||||
tools:text="@string/theme_true_black"/>
|
tools:text="@string/theme_true_black"/>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="48dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:layoutDirection="locale">
|
android:layoutDirection="locale">
|
||||||
<TextView
|
<TextView
|
||||||
@@ -12,7 +13,6 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="48dp"
|
|
||||||
android:paddingVertical="8dp"
|
android:paddingVertical="8dp"
|
||||||
android:paddingEnd="16dp"
|
android:paddingEnd="16dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:drawableLeft="@drawable/ic_fluent_people_community_24_regular"
|
|
||||||
android:drawableTint="?android:textColorSecondary"
|
android:drawableTint="?android:textColorSecondary"
|
||||||
android:drawablePadding="16dp"
|
android:drawablePadding="16dp"
|
||||||
android:textAppearance="@style/m3_title_medium"
|
android:textAppearance="@style/m3_title_medium"
|
||||||
@@ -26,6 +25,7 @@
|
|||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone"
|
||||||
android:paddingRight="16dp"/>
|
android:paddingRight="16dp"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@+id/open_with_account" android:title="@string/sk_open_with_account">
|
||||||
|
<menu android:id="@+id/accounts" />
|
||||||
|
</item>
|
||||||
<item android:id="@+id/edit" android:title="@string/edit"/>
|
<item android:id="@+id/edit" android:title="@string/edit"/>
|
||||||
<item android:id="@+id/delete" android:title="@string/delete"/>
|
<item android:id="@+id/delete" android:title="@string/delete"/>
|
||||||
<item android:id="@+id/delete_and_redraft" android:title="@string/sk_delete_and_redraft"/>
|
<item android:id="@+id/delete_and_redraft" android:title="@string/sk_delete_and_redraft"/>
|
||||||
@@ -11,5 +14,6 @@
|
|||||||
<item android:id="@+id/follow" android:title="@string/follow_user"/>
|
<item android:id="@+id/follow" android:title="@string/follow_user"/>
|
||||||
<item android:id="@+id/report" android:title="@string/report_user"/>
|
<item android:id="@+id/report" android:title="@string/report_user"/>
|
||||||
<item android:id="@+id/bookmark" android:title="@string/add_bookmark"/>
|
<item android:id="@+id/bookmark" android:title="@string/add_bookmark"/>
|
||||||
|
<item android:id="@+id/copy_link" android:title="@string/sk_copy_link_to_post"/>
|
||||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||||
</menu>
|
</menu>
|
||||||
@@ -2,5 +2,6 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:id="@+id/bookmarks" android:title="@string/bookmarks" android:icon="@drawable/ic_fluent_bookmark_multiple_24_regular" android:showAsAction="always"/>
|
<item android:id="@+id/bookmarks" android:title="@string/bookmarks" android:icon="@drawable/ic_fluent_bookmark_multiple_24_regular" android:showAsAction="always"/>
|
||||||
<item android:id="@+id/favorites" android:title="@string/your_favorites" android:icon="@drawable/ic_fluent_star_24_regular"/>
|
<item android:id="@+id/favorites" android:title="@string/your_favorites" android:icon="@drawable/ic_fluent_star_24_regular"/>
|
||||||
|
<item android:id="@+id/followed_hashtags" android:title="@string/sk_hashtags_you_follow" android:icon="@drawable/ic_fluent_number_symbol_24_regular"/>
|
||||||
<item android:id="@+id/share" android:title="@string/share_user" android:icon="@drawable/ic_fluent_share_24_regular"/>
|
<item android:id="@+id/share" android:title="@string/share_user" android:icon="@drawable/ic_fluent_share_24_regular"/>
|
||||||
</menu>
|
</menu>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<string name="sk_disable_marquee">Laufschrift in Titelleisten deaktivieren</string>
|
<string name="sk_disable_marquee">Laufschrift in Titelleisten deaktivieren</string>
|
||||||
<string name="sk_settings_contribute">Zu Megalodon beitragen</string>
|
<string name="sk_settings_contribute">Zu Megalodon beitragen</string>
|
||||||
<string name="sk_settings_show_federated_timeline">Föderierte Timeline anzeigen</string>
|
<string name="sk_settings_show_federated_timeline">Föderierte Timeline anzeigen</string>
|
||||||
<string name="sk_notify_posts">Beitrags-Benachrichtigungen</string>
|
<string name="sk_notify_posts">Beitrags-Benachrichtigungen</string>
|
||||||
<string name="sk_settings_color_palette">Farbschema</string>
|
<string name="sk_settings_color_palette">Farbschema</string>
|
||||||
<string name="sk_color_palette_pink">Pink</string>
|
<string name="sk_color_palette_pink">Pink</string>
|
||||||
<string name="sk_color_palette_purple">Violett</string>
|
<string name="sk_color_palette_purple">Violett</string>
|
||||||
@@ -58,13 +58,13 @@
|
|||||||
<string name="sk_clear_recent_languages">Zuletzt verwendete Sprachen leeren</string>
|
<string name="sk_clear_recent_languages">Zuletzt verwendete Sprachen leeren</string>
|
||||||
<string name="sk_welcome_title">Willkommen!</string>
|
<string name="sk_welcome_title">Willkommen!</string>
|
||||||
<string name="sk_example_domain">beispiel.social</string>
|
<string name="sk_example_domain">beispiel.social</string>
|
||||||
<string name="sk_welcome_text">Der Hai sagt Hi! Um anzufangen, bitte gib den Domain-Namen deiner Heim-Instanz unten ein.</string>
|
<string name="sk_welcome_text">Der Hai sagt Hi! Um anzufangen, bitte gib den Domain-Namen deiner Heim-Instanz unten ein.</string>
|
||||||
<string name="sk_color_palette_material3">System</string>
|
<string name="sk_color_palette_material3">System</string>
|
||||||
<string name="sk_color_palette_red">Rot</string>
|
<string name="sk_color_palette_red">Rot</string>
|
||||||
<string name="sk_settings_profile">Profil einrichten</string>
|
<string name="sk_settings_profile">Profil einrichten</string>
|
||||||
<string name="sk_settings_posting">Einstellungen für Beiträge</string>
|
<string name="sk_settings_posting">Einstellungen für Beiträge</string>
|
||||||
<string name="sk_settings_filters">Filter konfigurieren</string>
|
<string name="sk_settings_filters">Filter konfigurieren</string>
|
||||||
<string name="sk_settings_auth">Sicherheitseinstellungen</string>
|
<string name="sk_settings_auth">Sicherheits-Einstellungen</string>
|
||||||
<string name="sk_settings_rules">Regelwerk</string>
|
<string name="sk_settings_rules">Regelwerk</string>
|
||||||
<string name="sk_settings_about">Über die App</string>
|
<string name="sk_settings_about">Über die App</string>
|
||||||
<string name="sk_settings_donate">Spenden</string>
|
<string name="sk_settings_donate">Spenden</string>
|
||||||
@@ -73,12 +73,15 @@
|
|||||||
<string name="sk_delete_notification_confirm">Benachrichtigung wirklich löschen\?</string>
|
<string name="sk_delete_notification_confirm">Benachrichtigung wirklich löschen\?</string>
|
||||||
<string name="sk_clear_all_notifications_confirm_action">Alle löschen</string>
|
<string name="sk_clear_all_notifications_confirm_action">Alle löschen</string>
|
||||||
<string name="sk_enable_delete_notifications">Löschen von Benachrichtigungen aktivieren</string>
|
<string name="sk_enable_delete_notifications">Löschen von Benachrichtigungen aktivieren</string>
|
||||||
<string name="sk_settings_publish_button_text">Veröffentlichen-Button-Text</string>
|
<string name="sk_settings_publish_button_text">Veröffentlichen-Button-Text</string>
|
||||||
<string name="sk_settings_hide_translate_in_timeline">Übersetzen-Button in der Timeline ausblenden</string>
|
<string name="sk_settings_hide_translate_in_timeline">Übersetzen-Button in der Timeline ausblenden</string>
|
||||||
<string name="sk_delete_notification">Benachrichtigung löschen</string>
|
<string name="sk_delete_notification">Benachrichtigung löschen</string>
|
||||||
<string name="sk_clear_all_notifications">Alle Benachrichtigungen löschen</string>
|
<string name="sk_clear_all_notifications">Alle Benachrichtigungen löschen</string>
|
||||||
<string name="sk_settings_publish_button_text_title">Veröffentlichen-Button-Text anpassen</string>
|
<string name="sk_settings_publish_button_text_title">Veröffentlichen-Button-Text anpassen</string>
|
||||||
<string name="sk_clear_all_notifications_confirm">Wirklich alle Benachrichtigungen löschen\?</string>
|
<string name="sk_clear_all_notifications_confirm">Wirklich alle Benachrichtigungen löschen\?</string>
|
||||||
<string name="sk_settings_translation_availability_note_available">%s unterstützt Übersetzung!</string>
|
<string name="sk_settings_translation_availability_note_available">%s unterstützt Übersetzung!</string>
|
||||||
<string name="sk_settings_translation_availability_note_unavailable">%s scheint keine Übersetzung zu unterstützen.</string>
|
<string name="sk_settings_translation_availability_note_unavailable">%s scheint keine Übersetzung zu unterstützen.</string>
|
||||||
|
<string name="sk_loading_fediverse_resource_title">Suche im Fediverse…</string>
|
||||||
|
<string name="sk_undo_reblog">Reblog rückgängig machen</string>
|
||||||
|
<string name="sk_reblog_with_visibility">Rebloggen mit Sichtbarkeit</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -81,4 +81,8 @@
|
|||||||
<string name="sk_clear_all_notifications_confirm">¿Estás seguro de que quieres borrar todas las notificaciones\?</string>
|
<string name="sk_clear_all_notifications_confirm">¿Estás seguro de que quieres borrar todas las notificaciones\?</string>
|
||||||
<string name="sk_settings_translation_availability_note_available">¡%s admite traducción!</string>
|
<string name="sk_settings_translation_availability_note_available">¡%s admite traducción!</string>
|
||||||
<string name="sk_settings_translation_availability_note_unavailable">%s no parece soportar la traducción.</string>
|
<string name="sk_settings_translation_availability_note_unavailable">%s no parece soportar la traducción.</string>
|
||||||
|
<string name="sk_loading_fediverse_resource_title">Buscándolo en Fediverse…</string>
|
||||||
|
<string name="sk_quote_post">Publicar sobre esto</string>
|
||||||
|
<string name="sk_undo_reblog">Deshacer reblogueo</string>
|
||||||
|
<string name="sk_reblog_with_visibility">Rebloguea con visibilidad</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -81,4 +81,11 @@
|
|||||||
<string name="sk_settings_translation_availability_note_available">%s prend en charge la traduction !</string>
|
<string name="sk_settings_translation_availability_note_available">%s prend en charge la traduction !</string>
|
||||||
<string name="sk_settings_translation_availability_note_unavailable">%s ne semble pas prendre en charge la traduction.</string>
|
<string name="sk_settings_translation_availability_note_unavailable">%s ne semble pas prendre en charge la traduction.</string>
|
||||||
<string name="sk_clear_all_notifications_confirm">Voulez-vous vraiment supprimer toutes les notifications \?</string>
|
<string name="sk_clear_all_notifications_confirm">Voulez-vous vraiment supprimer toutes les notifications \?</string>
|
||||||
|
<string name="sk_loading_fediverse_resource_title">Le rechercher sur le Fediverse…</string>
|
||||||
|
<string name="sk_reblog_with_visibility">Rebloguer avec visibilité</string>
|
||||||
|
<string name="sk_undo_reblog">Annuler le reblogage</string>
|
||||||
|
<string name="sk_quote_post">Poster à ce sujet</string>
|
||||||
|
<string name="sk_hashtags_you_follow">Hashtags que vous suivez</string>
|
||||||
|
<string name="sk_open_in_account">Ouvrir dans un autre compte</string>
|
||||||
|
<string name="sk_copy_link_to_post">Copier le lien du post</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -61,4 +61,31 @@
|
|||||||
<string name="sk_color_palette_red">Merah</string>
|
<string name="sk_color_palette_red">Merah</string>
|
||||||
<string name="sk_translated_using">Diterjemahkan menggunakan %s</string>
|
<string name="sk_translated_using">Diterjemahkan menggunakan %s</string>
|
||||||
<string name="sk_welcome_text">Hiu menyapamu! Untuk memulai, silakan memasukkan nama domain instansi Anda di bawah.</string>
|
<string name="sk_welcome_text">Hiu menyapamu! Untuk memulai, silakan memasukkan nama domain instansi Anda di bawah.</string>
|
||||||
|
<string name="sk_tabs_disable_swipe">Nonaktifkan mengusap antara tab</string>
|
||||||
|
<string name="sk_settings_profile">Atur profil</string>
|
||||||
|
<string name="sk_settings_filters">Atur profil</string>
|
||||||
|
<string name="sk_enable_delete_notifications">Aktifkan menghapus notifikasi</string>
|
||||||
|
<string name="sk_settings_publish_button_text">Teks tombol Terbitkan</string>
|
||||||
|
<string name="sk_settings_publish_button_text_title">Ubah teks tombol Terbitkan</string>
|
||||||
|
<string name="sk_settings_hide_translate_in_timeline">Sembunyikan tombol terjemahkan di lini masa</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_available">%s mendukung penerjemahan!</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_unavailable">%s sepertinya tidak mendukung penerjemahan.</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm">Apakah Anda yakin ingin menghapus semua notifikasi\?</string>
|
||||||
|
<string name="sk_loading_fediverse_resource_title">Mencari di Fedimesta…</string>
|
||||||
|
<string name="sk_settings_rules">Aturan</string>
|
||||||
|
<string name="sk_settings_about">Tentang aplikasi</string>
|
||||||
|
<string name="sk_settings_donate">Donasi</string>
|
||||||
|
<string name="sk_delete_notification">Hapus notifikasi</string>
|
||||||
|
<string name="sk_delete_notification_confirm_action">Hapus notifikasi</string>
|
||||||
|
<string name="sk_delete_notification_confirm">Apakah kamu yakin ingin menghapus notifikasi ini\?</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm_action">Hapus semua</string>
|
||||||
|
<string name="sk_settings_posting">Preferensi kiriman</string>
|
||||||
|
<string name="sk_settings_auth">Pengaturan keamanan</string>
|
||||||
|
<string name="sk_clear_all_notifications">Hapus semua notifikasi</string>
|
||||||
|
<string name="sk_undo_reblog">Urungkan pembagian</string>
|
||||||
|
<string name="sk_quote_post">Kirim tentang ini</string>
|
||||||
|
<string name="sk_reblog_with_visibility">Bagikan dengan keterlihatan</string>
|
||||||
|
<string name="sk_copy_link_to_post">Salin tautan ke kiriman</string>
|
||||||
|
<string name="sk_open_in_account">Buka di akun lain</string>
|
||||||
|
<string name="sk_hashtags_you_follow">Tagar yang Anda ikuti</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -61,4 +61,25 @@
|
|||||||
<string name="sk_welcome_text">상어가 당신을 맞이합니다! 시작하기 위해, 아래에 사용하시는 인스턴스의 도메인 이름을 입력해주세요.</string>
|
<string name="sk_welcome_text">상어가 당신을 맞이합니다! 시작하기 위해, 아래에 사용하시는 인스턴스의 도메인 이름을 입력해주세요.</string>
|
||||||
<string name="sk_color_palette_material3">시스템</string>
|
<string name="sk_color_palette_material3">시스템</string>
|
||||||
<string name="sk_color_palette_red">빨간색</string>
|
<string name="sk_color_palette_red">빨간색</string>
|
||||||
|
<string name="sk_settings_profile">프로필 설정</string>
|
||||||
|
<string name="sk_settings_posting">게시물 설정</string>
|
||||||
|
<string name="sk_settings_filters">필터 설정</string>
|
||||||
|
<string name="sk_settings_auth">보안 설정</string>
|
||||||
|
<string name="sk_settings_rules">서버 규칙</string>
|
||||||
|
<string name="sk_settings_about">이 앱에 관하여</string>
|
||||||
|
<string name="sk_settings_donate">기부</string>
|
||||||
|
<string name="sk_delete_notification_confirm_action">알림 삭제</string>
|
||||||
|
<string name="sk_delete_notification_confirm">정말로 이 알림을 삭제하시겠습니까\?</string>
|
||||||
|
<string name="sk_enable_delete_notifications">알림 삭제 활성화</string>
|
||||||
|
<string name="sk_settings_publish_button_text">게시 버튼 텍스트</string>
|
||||||
|
<string name="sk_settings_publish_button_text_title">게시 버튼 사용자화</string>
|
||||||
|
<string name="sk_settings_hide_translate_in_timeline">타임라인에서 번역 버튼 숨김</string>
|
||||||
|
<string name="sk_delete_notification">알림 삭제</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_available">%s 서버는 번역을 지원합니다!</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_unavailable">%s 서버는 번역을 지원하지 않는 것 같습니다.</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm">정말로 모든 알림을 삭제하시겠습니까\?</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm_action">모두 삭제</string>
|
||||||
|
<string name="sk_tabs_disable_swipe">스와이프로 탭간 전환 비활성화</string>
|
||||||
|
<string name="sk_clear_all_notifications">모든 알림 삭제</string>
|
||||||
|
<string name="sk_loading_fediverse_resource_title">연합우주에서 찾아보는 중…</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -59,4 +59,30 @@
|
|||||||
<string name="sk_example_domain">example.social</string>
|
<string name="sk_example_domain">example.social</string>
|
||||||
<string name="sk_welcome_title">Вітаємо!</string>
|
<string name="sk_welcome_title">Вітаємо!</string>
|
||||||
<string name="sk_welcome_text">Акулка вас вітає! Щоб розпочати, введіть нижче доменне ім’я вашого інстансу.</string>
|
<string name="sk_welcome_text">Акулка вас вітає! Щоб розпочати, введіть нижче доменне ім’я вашого інстансу.</string>
|
||||||
|
<string name="sk_settings_profile">Налаштувати профіль</string>
|
||||||
|
<string name="sk_settings_posting">Налаштувати постинг</string>
|
||||||
|
<string name="sk_settings_filters">Налаштувати фільтри</string>
|
||||||
|
<string name="sk_settings_rules">Правила</string>
|
||||||
|
<string name="sk_settings_about">Про застосунок</string>
|
||||||
|
<string name="sk_settings_donate">Донат</string>
|
||||||
|
<string name="sk_color_palette_material3">Системна</string>
|
||||||
|
<string name="sk_color_palette_red">Червона</string>
|
||||||
|
<string name="sk_delete_notification">Видалити сповіщення</string>
|
||||||
|
<string name="sk_delete_notification_confirm_action">Видалити</string>
|
||||||
|
<string name="sk_delete_notification_confirm">Ви впевнені, що хочете видалити це сповіщення\?</string>
|
||||||
|
<string name="sk_enable_delete_notifications">Увімкнути видалення сповіщень</string>
|
||||||
|
<string name="sk_settings_publish_button_text">Текст кнопки \"опублікувати\"</string>
|
||||||
|
<string name="sk_settings_publish_button_text_title">Змінити текст кнопки \"опублікувати\"</string>
|
||||||
|
<string name="sk_settings_hide_translate_in_timeline">Сховати кнопку \"перекласти\" у стрічці</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_available">%s підтримує переклад!</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_unavailable">%s не підтримує переклад.</string>
|
||||||
|
<string name="sk_clear_all_notifications">Очистити всі сповіщення</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm">Ви впевнені, що хочете очистити всі сповіщення\?</string>
|
||||||
|
<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_tabs_disable_swipe">Вимкнути перегортання вкладок</string>
|
||||||
|
<string name="sk_settings_auth">Налаштування безпеці</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm_action">Видалити все</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -47,4 +47,42 @@
|
|||||||
<string name="sk_color_palette_yellow">黄</string>
|
<string name="sk_color_palette_yellow">黄</string>
|
||||||
<string name="sk_notification_type_status">嘟文</string>
|
<string name="sk_notification_type_status">嘟文</string>
|
||||||
<string name="sk_notify_posts">嘟文通知</string>
|
<string name="sk_notify_posts">嘟文通知</string>
|
||||||
|
<string name="sk_translate_post">翻译</string>
|
||||||
|
<string name="sk_translate_show_original">显示原文</string>
|
||||||
|
<string name="sk_poll_allow_multiple">允许多选</string>
|
||||||
|
<string name="sk_welcome_text">鲨鱼向你致敬!要想开始,请在下面输入你的账户所在实例的域名。</string>
|
||||||
|
<string name="sk_welcome_title">欢迎!</string>
|
||||||
|
<string name="sk_clear_recent_languages">清除最近使用的语言</string>
|
||||||
|
<string name="sk_confirm_clear_recent_languages">您确定要清除最近使用的语言吗?</string>
|
||||||
|
<string name="sk_translated_using">使用 %s 翻译</string>
|
||||||
|
<string name="sk_post_language">语言: %s</string>
|
||||||
|
<string name="sk_available_languages">可用语言</string>
|
||||||
|
<string name="sk_language_name">%s (%s)</string>
|
||||||
|
<string name="sk_example_domain">example.social</string>
|
||||||
|
<string name="sk_tabs_disable_swipe">禁用选项卡之间的滑动</string>
|
||||||
|
<string name="sk_settings_profile">设置个人资料</string>
|
||||||
|
<string name="sk_settings_posting">发布偏好</string>
|
||||||
|
<string name="sk_settings_filters">配置过滤器</string>
|
||||||
|
<string name="sk_settings_auth">安全设置</string>
|
||||||
|
<string name="sk_settings_rules">规则</string>
|
||||||
|
<string name="sk_settings_about">关于应用程序</string>
|
||||||
|
<string name="sk_settings_donate">捐赠</string>
|
||||||
|
<string name="sk_color_palette_material3">系统</string>
|
||||||
|
<string name="sk_color_palette_red">红</string>
|
||||||
|
<string name="sk_delete_notification_confirm">您确定要删除此通知吗?</string>
|
||||||
|
<string name="sk_enable_delete_notifications">启用删除通知</string>
|
||||||
|
<string name="sk_delete_notification">删除通知</string>
|
||||||
|
<string name="sk_delete_notification_confirm_action">删除通知</string>
|
||||||
|
<string name="sk_settings_publish_button_text">发布按钮文本</string>
|
||||||
|
<string name="sk_settings_publish_button_text_title">自定义发布按钮文本</string>
|
||||||
|
<string name="sk_settings_hide_translate_in_timeline">在时间轴中隐藏翻译按钮</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_available">%s 支持翻译!</string>
|
||||||
|
<string name="sk_settings_translation_availability_note_unavailable">%s 似乎不支持翻译。</string>
|
||||||
|
<string name="sk_clear_all_notifications">清除所有通知</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm_action">删除所有</string>
|
||||||
|
<string name="sk_clear_all_notifications_confirm">您确定要清除所有通知吗?</string>
|
||||||
|
<string name="sk_loading_fediverse_resource_title">在 Fediverse 上查找它……</string>
|
||||||
|
<string name="sk_undo_reblog">撤销转发</string>
|
||||||
|
<string name="sk_reblog_with_visibility">转发可见性</string>
|
||||||
|
<string name="sk_quote_post">关于这个嘟文</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -82,5 +82,13 @@
|
|||||||
<string name="sk_settings_hide_translate_in_timeline">Hide translate button in timeline</string>
|
<string name="sk_settings_hide_translate_in_timeline">Hide translate button in timeline</string>
|
||||||
<string name="sk_settings_translation_availability_note_available">%s supports translation!</string>
|
<string name="sk_settings_translation_availability_note_available">%s supports translation!</string>
|
||||||
<string name="sk_settings_translation_availability_note_unavailable">%s does not appear to support translation.</string>
|
<string name="sk_settings_translation_availability_note_unavailable">%s does not appear to support translation.</string>
|
||||||
<string name="sk_loading_fediverse_resource_title">Looking it up on the Fediverse…</string>
|
<string name="sk_loading_fediverse_resource_title">Looking it up on the Fediverse</string>
|
||||||
|
<string name="sk_loading_resource_on_instance_title">Looking it up on %s</string>
|
||||||
|
<string name="sk_undo_reblog">Undo reblog</string>
|
||||||
|
<string name="sk_reblog_with_visibility">Reblog with visibility</string>
|
||||||
|
<string name="sk_quote_post">Post about this</string>
|
||||||
|
<string name="sk_hashtags_you_follow">Hashtags you follow</string>
|
||||||
|
<string name="sk_copy_link_to_post">Copy link to post</string>
|
||||||
|
<string name="sk_open_with_account">Open with other account</string>
|
||||||
|
<string name="sk_resource_not_found">Resource could not be found</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -307,7 +307,7 @@
|
|||||||
<!-- colors -->
|
<!-- colors -->
|
||||||
<item name="android:colorAccent">?colorPrimary700</item>
|
<item name="android:colorAccent">?colorPrimary700</item>
|
||||||
<item name="android:colorPrimary">?colorGray800</item>
|
<item name="android:colorPrimary">?colorGray800</item>
|
||||||
<item name="android:colorBackground">?colorGray100</item>
|
<item name="android:colorBackground">?colorBackgroundPopup</item>
|
||||||
<item name="android:textColorPrimary">?colorGray800</item>
|
<item name="android:textColorPrimary">?colorGray800</item>
|
||||||
<item name="android:textColorSecondary">?colorGray500</item>
|
<item name="android:textColorSecondary">?colorGray500</item>
|
||||||
</style>
|
</style>
|
||||||
@@ -321,7 +321,7 @@
|
|||||||
<!-- colors -->
|
<!-- colors -->
|
||||||
<item name="android:colorAccent">?colorPrimary600</item>
|
<item name="android:colorAccent">?colorPrimary600</item>
|
||||||
<item name="android:colorPrimary">?colorGray50</item>
|
<item name="android:colorPrimary">?colorGray50</item>
|
||||||
<item name="android:colorBackground">?colorGray700</item>
|
<item name="android:colorBackground">?colorBackgroundPopup</item>
|
||||||
<item name="android:textColorPrimary">?colorGray50</item>
|
<item name="android:textColorPrimary">?colorGray50</item>
|
||||||
<item name="android:textColorSecondary">?colorGray400</item>
|
<item name="android:textColorSecondary">?colorGray400</item>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
— S'han preparat els fitxers per al llançament a F-Droid
|
- S'han preparat els fitxers per al llançament a F-Droid
|
||||||
— S'ha solucionat l'actualització automàtica
|
- S'ha solucionat l'actualització automàtica
|
||||||
— S'han afegit icones monocromàtiques per a les icones del menú d'aplicacions
|
- S'han afegit icones monocromàtiques per a les icones del menú d'aplicacions
|
||||||
— S'ha canviat la icona de «No llistat» incorrecta al peu de pàgina ampliat
|
- S'ha canviat la icona de «No llistat» incorrecta al peu de pàgina ampliat
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
— És possible obrir la publicació original mentre respons (fent clic a la línia «En resposta a…»)
|
- És possible obrir la publicació original mentre respons (fent clic a la línia «En resposta a…»)
|
||||||
— Ha combinat els canvis de la font superior i correccions d'errors
|
- Ha combinat els canvis de la font superior i correccions d'errors
|
||||||
— S'ha eliminat el codi «Centre d'aplicacions» no utilitzat
|
- S'ha eliminat el codi «Centre d'aplicacions» no utilitzat
|
||||||
— S'ha afegit una versió sense línia de temps federada per a la Play Store
|
- S'ha afegit una versió sense línia de temps federada per a la Play Store
|
||||||
— S'ha afegit un URI de redirecció personalitzat per a facilitar l'inici de sessió
|
- S'ha afegit un URI de redirecció personalitzat per a facilitar l'inici de sessió
|
||||||
— S'ha canviat l'enllaç de contribució
|
- S'ha canviat l'enllaç de contribució
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
- Boost-Button gedrückt halten zum Drüber-Kommentieren
|
- Boost-Button gedrückt halten zum Drüber-Kommentieren
|
||||||
- Teilen-Button gedrückt halten, um den Link zu kopieren
|
- Teilen-Button gedrückt halten, um den Link zu kopieren
|
||||||
- Benachrichtigungen löschen (standardmäßig deaktiviert)
|
- Benachrichtigungen löschen (standardmäßig deaktiviert)
|
||||||
- Extra Symbole für die einzelnen Benachrichtigungs-Typen
|
- Extra Symbole für Benachrichtigungs-Typen
|
||||||
- Neue Grautöne
|
- Neue Grautöne
|
||||||
- Einstellung, um Wischen zwischen Tabs auszuschalten
|
- Wischen zwischen Tabs ausschaltbar
|
||||||
- Verschiedene Links zu Kontoeinstellungen hinzugefügt
|
- Links zu Kontoeinstellungen hinzugefügt
|
||||||
- Einstellung, um den Übersetzen-Button in der Timeline zu verbergen/anzuzeigen
|
- Einstellung, um den Übersetzen-Button in der Timeline anzuzeigen
|
||||||
- Fehlerbehebungen und Anpassungen
|
- Fehlerbehebungen
|
||||||
6
metadata/de-DE/changelogs/63.txt
Normal file
6
metadata/de-DE/changelogs/63.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- Option zum Auswählen der Sichtbarkeit durch Gedrückthalten des Reblog-Buttons
|
||||||
|
- Sichtbarkeit eigener Reblogs wird nun angezeigt
|
||||||
|
- Liste der gefolgten Hashtags hinzugefügt
|
||||||
|
- Links gedrückt halten, um sie zu kopieren
|
||||||
|
- Option, um Beiträge mit einem anderen Konto zu öffnen
|
||||||
|
- Fehlerbehebungen und kleinere Tweaks
|
||||||
6
metadata/en-US/changelogs/63.txt
Normal file
6
metadata/en-US/changelogs/63.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- Option to reblog with specific visibility on long-click
|
||||||
|
- Show visibility of own reblogs
|
||||||
|
- Add list of followed hashtags
|
||||||
|
- Long-click to copy links
|
||||||
|
- Option to open posts with other account
|
||||||
|
- Bugfixes and minor tweaks
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
— Se han preparado los archivos para el lanzamiento en F-Droid
|
- Se han preparado los archivos para el lanzamiento en F-Droid
|
||||||
— Se ha solucionado la actualización automática
|
- Se ha solucionado la actualización automática
|
||||||
— Se han añadido iconos monocromáticos para los iconos del menú de aplicaciones
|
- Se han añadido iconos monocromáticos para los iconos del menú de aplicaciones
|
||||||
— Se ha cambiado el icono de «No listado» incorrecto en el pie de página ampliado
|
- Se ha cambiado el icono de «No listado» incorrecto en el pie de página ampliado
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
— Es posible abrir la publicación original mientras respondes (haciendo clic en la línea "En respuesta a…")
|
- Es posible abrir la publicación original mientras respondes (haciendo clic en la línea "En respuesta a…")
|
||||||
— Ha combinado los cambios de la fuente superior y correcciones de errores
|
- Ha combinado los cambios de la fuente superior y correcciones de errores
|
||||||
— Se ha eliminado el código "Centro de aplicaciones" no utilizado
|
- Se ha eliminado el código "Centro de aplicaciones" no utilizado
|
||||||
— Se ha añadido una versión sin línea de tiempo federada para Play Store
|
- Se ha añadido una versión sin línea de tiempo federada para Play Store
|
||||||
— Se ha añadido un URI de redirección personalizado para facilitar el inicio de sesión
|
- Se ha añadido un URI de redirección personalizado para facilitar el inicio de sesión
|
||||||
— Se ha cambiado el enlace de las contribuciones
|
- Se ha cambiado el enlace de las contribuciones
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
- Copiar la URL de la entrada al pulsar prolongadamente el botón de compartir
|
|
||||||
- Añadir la opción de desactivar el deslizamiento entre pestañas
|
|
||||||
- Nuevos colores grises
|
|
||||||
- Eliminar notificaciones (desactivado por defecto)
|
|
||||||
- Añadir varios enlaces a la configuración de la cuenta
|
|
||||||
- Botón de publicación personalizable
|
- Botón de publicación personalizable
|
||||||
|
- Abrir enlaces de Fediverse en la aplicación
|
||||||
|
- Botón boost de pulsación larga para "citar" un post
|
||||||
|
- Copiar la URL de la publicación al pulsar prolongadamente el botón de compartir
|
||||||
|
- Implementar la eliminación de notificaciones (desactivada por defecto)
|
||||||
- Iconos específicos para los distintos tipos de notificaciones
|
- Iconos específicos para los distintos tipos de notificaciones
|
||||||
|
- Nuevos colores grises
|
||||||
|
- Añadir la opción de desactivar el deslizamiento entre pestañas.
|
||||||
|
- Añadir varios enlaces a la configuración de la cuenta
|
||||||
- Mostrar/ocultar el botón de traducción en la línea de tiempo
|
- Mostrar/ocultar el botón de traducción en la línea de tiempo
|
||||||
- Corrección de errores y ajustes (botón Marcador, animaciones de los botones)
|
- Corrección de errores y ajustes
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
- Copier l'URL du post avec un appuis long sur le bouton de partage
|
- Bouton Publier perso.
|
||||||
- Ajout d'une option pour désactiver le balayage entre les onglets
|
- Ouverture des liens Fediverse dans l'application
|
||||||
|
- Clic long sur le bouton boost pour citer un message
|
||||||
|
- Copier l'URL du post avec appuis long sur le bouton de partage
|
||||||
|
- Ajout de la suppr. des notifs.
|
||||||
|
- Icônes pour différents types de notification
|
||||||
- Nouvelles couleurs grises
|
- Nouvelles couleurs grises
|
||||||
- Ajout de la suppression des notifications
|
- Possibilité de désactiver le balayage entre les onglets
|
||||||
- Ajout de divers liens vers les paramètres du compte
|
- Ajout de liens vers les paramètres du compte
|
||||||
- Bouton Publier personnalisable
|
|
||||||
- Icônes dédiées pour différents types de notification
|
|
||||||
- Option pour afficher/masquer le bouton de traduction dans la timeline
|
- Option pour afficher/masquer le bouton de traduction dans la timeline
|
||||||
- Corrections de bugs et ajustements (bouton de signet, animations de bouton)
|
- Correction de bugs
|
||||||
|
|||||||
3
metadata/fr-FR/changelogs/63.txt
Normal file
3
metadata/fr-FR/changelogs/63.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- Rebloguer avec une visibilité spécifique sur clic long
|
||||||
|
- Liste des hashtags suivis
|
||||||
|
- Cliquez longuement sur les liens pour les copier
|
||||||
5
metadata/id/changelogs/61.txt
Normal file
5
metadata/id/changelogs/61.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
- Tema warna baru: Material You dan Merah
|
||||||
|
- Tanda abu-abu gelap baru untuk semua tema
|
||||||
|
- Ikon bagikan lebih jelas
|
||||||
|
- Animasi untuk tombol interaksi
|
||||||
|
- Perbaikan kutu (Mogok pada beberapa kiriman, "Daftar dengan", bahasa kiriman bawaan)
|
||||||
11
metadata/id/changelogs/62.txt
Normal file
11
metadata/id/changelogs/62.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- Tombol Terbitkan dapat diubah
|
||||||
|
- Buka tautan Fedimesta dlm aplikasi
|
||||||
|
- Klik lama pada tombol boost utk "mengutip" kiriman
|
||||||
|
- Salin URL kiriman ketika menekan lama pada tombol bagikan
|
||||||
|
- Terapkan penghapusan notifikasi (dinonaktifkan secara bawaan)
|
||||||
|
- Ikon tersendiri utk jenis notifikasi berbeda
|
||||||
|
- Warna abu-abu baru
|
||||||
|
- Tambah pengaturan utk menonaktifkan pengusapan antara tab
|
||||||
|
- Tambah tautan ke pengaturan akun
|
||||||
|
- Saklar menampilkan/menyembunyikan tombol terjemahkan dalam lini masa
|
||||||
|
- Banyak perbaikan
|
||||||
3
metadata/id/changelogs/63.txt
Normal file
3
metadata/id/changelogs/63.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- Bagikan dengan keterlihatan khusu pada klik lama
|
||||||
|
- Daftar tagar yang diikuti
|
||||||
|
- Klik lama pada tautan untuk menyalinnya
|
||||||
5
metadata/ko/changelogs/61.txt
Normal file
5
metadata/ko/changelogs/61.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
- 새로운 색상 테마: Material You와 빨간색
|
||||||
|
- 모든 테마에 새로운 회색 톤 적용
|
||||||
|
- 부스트 아이콘을 더 뚜렷하게 채움
|
||||||
|
- 반응 버튼에 애니메이션 적용
|
||||||
|
- 버그 수정 (일부 게시물로 인한 오류, "...님이 포함된 리스트", 기본 게시물 언어)
|
||||||
11
metadata/ko/changelogs/62.txt
Normal file
11
metadata/ko/changelogs/62.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- 게시 버튼을 커스텀 가능함
|
||||||
|
- 연합우주 링크를 앱으로 열 수 있음
|
||||||
|
- 부스트 버튼을 길게 눌러 게시물 "인용"
|
||||||
|
- 공유 버튼을 길게 눌러 게시물 URL 복사
|
||||||
|
- 알림 삭제 기능 추가 (기본적으로 비활성화)
|
||||||
|
- 서로 다른 알림 유형에 따라 다르게 표시되는 아이콘
|
||||||
|
- 새로운 회색 색상 적용
|
||||||
|
- 스와이프로 탭간 전환할 수 있는 기능 비활성화 설정 추가
|
||||||
|
- 계정 설정과 관련된 여러 링크 추가
|
||||||
|
- 번역 버튼을 타임라인에 표시하거나 숨길 수 있는 설정 추가
|
||||||
|
- 버그 수정 및 개선
|
||||||
5
metadata/uk/changelogs/61.txt
Normal file
5
metadata/uk/changelogs/61.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
- Нові колірні теми: Material You й Червона
|
||||||
|
- Нові темно-сірі тони для всіх тем
|
||||||
|
- Більш виразний заповнений значок репоста
|
||||||
|
- Анімації для кнопок взаємодій
|
||||||
|
- Виправлення багів (виліт на деякіх постах, тощо)
|
||||||
4
metadata/zh-Hans/changelogs/50.txt
Normal file
4
metadata/zh-Hans/changelogs/50.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
- 准备文件以便在F-Droid上发布
|
||||||
|
- 修复自动更新程序
|
||||||
|
- 将单色图标重新添加到启动器图标
|
||||||
|
- 替换发布页脚中错误的不公开图标
|
||||||
6
metadata/zh-Hans/changelogs/51.txt
Normal file
6
metadata/zh-Hans/changelogs/51.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- 使得在回复时可以打开原帖(通过点击 "回复...... "一行)。
|
||||||
|
- 合并上游的修改和错误修正
|
||||||
|
- 删除未使用的 "App Center" 代码
|
||||||
|
- 为Play Store添加没有联邦时间轴的版本
|
||||||
|
- 添加自定义重定向URI以方便登录
|
||||||
|
- 更改贡献链接
|
||||||
4
metadata/zh-Hans/changelogs/55.txt
Normal file
4
metadata/zh-Hans/changelogs/55.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
- 修复损坏的 HTML 标签并启用以 Markdown 格式呈现
|
||||||
|
- 初始化 <a href="https://translate.codeberg.org/projects/megalodon">Weblate 翻译项目</a>
|
||||||
|
- 为联邦时间线添加切换
|
||||||
|
- 版本 52-54 是针对 Google Play 版本的小幅调整
|
||||||
6
metadata/zh-Hans/changelogs/56.txt
Normal file
6
metadata/zh-Hans/changelogs/56.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- @LucasGGamerM 自定义颜色主题
|
||||||
|
- 由@LucasGGamerM 提交的新“megalodon”文字标识
|
||||||
|
- 创作时更好的表情符号搜索
|
||||||
|
- 调整投票(显示自己的投票,始终显示投票按钮,不要切断长答案)
|
||||||
|
- 为嘟文通知添加推送通知设置
|
||||||
|
- Bug修复
|
||||||
6
metadata/zh-Hans/changelogs/59.txt
Normal file
6
metadata/zh-Hans/changelogs/59.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- 添加语言选择器
|
||||||
|
- 添加翻译功能
|
||||||
|
- 改进投票投票的语义(单选按钮和复选框)
|
||||||
|
- 添加选项以允许对民意调查中的多个选项进行投票
|
||||||
|
- 新的登录屏幕
|
||||||
|
- Bug修复
|
||||||
5
metadata/zh-Hans/changelogs/61.txt
Normal file
5
metadata/zh-Hans/changelogs/61.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
- 新的颜色主题:Material You 和 红
|
||||||
|
- 所有主题的新深灰色调
|
||||||
|
- 更明显的填充提升图标
|
||||||
|
- 交互按钮的动画
|
||||||
|
- 错误修正(某些嘟文崩溃,“列表为”,默认发布语言)
|
||||||
11
metadata/zh-Hans/changelogs/62.txt
Normal file
11
metadata/zh-Hans/changelogs/62.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- 可定制的发布按钮
|
||||||
|
- 在应用程序中打开 Fediverse 链接
|
||||||
|
- 长按转发按钮以“引用”嘟文
|
||||||
|
- 长按分享按钮时复制帖子网址
|
||||||
|
- 实施删除通知(默认禁用)
|
||||||
|
- 不同通知类型的专用图标
|
||||||
|
- 新的灰色
|
||||||
|
- 添加设置以禁用选项卡之间的滑动
|
||||||
|
- 添加各种链接到帐户设置
|
||||||
|
- 切换显示/隐藏时间轴中的翻译按钮
|
||||||
|
- 错误修正和调整
|
||||||
15
metadata/zh-Hans/full_description.txt
Normal file
15
metadata/zh-Hans/full_description.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Megalodon 是<a href="https://github.com/mastodon/mastodon-android">官方 Mastodon Android 应用</a>的修改版本,添加了官方应用中缺少的重要功能,例如联合时间轴、不公开的帖子和图像描述查看器。
|
||||||
|
|
||||||
|
<b>主要特点</b>
|
||||||
|
|
||||||
|
- <b>不公开的帖子</b>:公开发布而不让您的帖子出现在趋势、标签或公共时间轴中。
|
||||||
|
- <b>联邦时间轴</b>:查看您的实例连接到的所有其他 Fediverse 社区的人们的所有公开帖子。
|
||||||
|
- <b>图片描述查看器</b>:快速检查图片或视频是否附加了替代文字。
|
||||||
|
- <b>置顶帖子</b>:将您最重要的帖子置顶到您的个人资料,并使用“置顶”选项卡查看其他人固定的内容。
|
||||||
|
- <b>关注话题标签</b>:通过关注直接在您的主页时间线中查看来自特定话题标签的新帖子。
|
||||||
|
- <b>回应关注请求</b>:接受或拒绝来自您的通知或专用关注请求列表的关注请求。
|
||||||
|
- <b>删除和重新起草</b>:这个备受喜爱的功能使编辑成为可能,而无需实际的编辑功能。
|
||||||
|
- <b>语言选择器</b>:为您发布的每个帖子轻松选择语言,以便过滤器和翻译正常工作。
|
||||||
|
- <b>翻译</b>:在 Megalodon 内轻松翻译帖子! 该功能仅在在您的 Mastodon Web 上也可用时才有效。
|
||||||
|
- <b>帖子可见性指示器</b>:打开或回复帖子时,将显示一个指示帖子可见性的便捷图标。
|
||||||
|
- <b>颜色主题</b>:如果您不喜欢默认的粉红色(鲨鱼在默默地评判您),Moshidon 的颜色主题可以满足您的需求。
|
||||||
Reference in New Issue
Block a user