Compare commits
51 Commits
v1.1.4+for
...
v1.1.4+for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53cb809996 | ||
|
|
ff0a77d6b5 | ||
|
|
596ec3230f | ||
|
|
fa75c8eb6f | ||
|
|
6c7a17fb81 | ||
|
|
0ad8f926cc | ||
|
|
764ab60fea | ||
|
|
9b13bdb06f | ||
|
|
9283ca8878 | ||
|
|
679ede1124 | ||
|
|
f4b1bde8c5 | ||
|
|
eff6cc3e17 | ||
|
|
03044b86b1 | ||
|
|
90ff88f02b | ||
|
|
e1f378977a | ||
|
|
a0f3d2862c | ||
|
|
0c64145368 | ||
|
|
a1474fb461 | ||
|
|
965ebc8669 | ||
|
|
3514152439 | ||
|
|
1b1dc7085e | ||
|
|
94d004724f | ||
|
|
e9f5d235cb | ||
|
|
9692afb323 | ||
|
|
3ae37a700b | ||
|
|
b166ca705e | ||
|
|
e6a67543f4 | ||
|
|
7d38f031f1 | ||
|
|
cf864e6f49 | ||
|
|
f4b1629a1d | ||
|
|
1fbb97021e | ||
|
|
229c815a59 | ||
|
|
ee8d78637d | ||
|
|
4ede842171 | ||
|
|
8306e78ce3 | ||
|
|
65d093ee9d | ||
|
|
aa48233a75 | ||
|
|
ae50e618c0 | ||
|
|
defa8b014e | ||
|
|
159d91f390 | ||
|
|
430d4ec93b | ||
|
|
ae64784daf | ||
|
|
18df7c32a4 | ||
|
|
4615612a65 | ||
|
|
6b226cdcad | ||
|
|
1776709b38 | ||
|
|
75a35cd680 | ||
|
|
18d4f2fa36 | ||
|
|
bca936f6a2 | ||
|
|
0b59379c4e | ||
|
|
21a526dda9 |
28
README.md
28
README.md
@@ -10,22 +10,28 @@
|
||||
|
||||
### Features
|
||||
|
||||
* [Add “Unlisted” as a post visibility option](https://github.com/sk22/mastodon-android-fork/tree/feature/enable-unlisted)
|
||||
* [Add “Unlisted” as a post visibility option](https://github.com/sk22/mastodon-android-fork/commits/feature/enable-unlisted)
|
||||
([Pull request](https://github.com/mastodon/mastodon-android/pull/103))
|
||||
* [Add “Federation” tab and change Discover tab order](https://github.com/sk22/mastodon-android-fork/tree/feature/add-federated-timeline) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/8))
|
||||
* [Add image description button and viewer](https://github.com/sk22/mastodon-android-fork/tree/feature/display-alt-text) ([Pull request](https://github.com/mastodon/mastodon-android/pull/129))
|
||||
* [Implement pinning posts and displaying pinned posts](https://github.com/sk22/mastodon-android-fork/tree/feature/pin-posts) ([Pull request](https://github.com/mastodon/mastodon-android/pull/140))
|
||||
* [Implement a bookmark button and list](https://github.com/sk22/mastodon-android-fork/tree/feature/bookmarks) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/22))
|
||||
* [Add “Mark media as sensitive” option](https://github.com/sk22/mastodon-android-fork/tree/feature/mark-media-as-sensitive)
|
||||
* [Add “Federation” tab and change Discover tab order](https://github.com/sk22/mastodon-android-fork/commits/feature/add-federated-timeline) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/8))
|
||||
* [Add image description button and viewer](https://github.com/sk22/mastodon-android-fork/commits/feature/display-alt-text) ([Pull request](https://github.com/mastodon/mastodon-android/pull/129))
|
||||
* [Implement pinning posts and displaying pinned posts](https://github.com/sk22/mastodon-android-fork/commits/feature/pin-posts) ([Pull request](https://github.com/mastodon/mastodon-android/pull/140))
|
||||
* [Implement deleting and re-drafting](https://github.com/sk22/mastodon-android-fork/commits/feature/delete-redraft) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/21))
|
||||
* [Implement a bookmark button and list](https://github.com/sk22/mastodon-android-fork/commits/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/sk22/mastodon-android-fork/commits/feature/check-for-update-button)
|
||||
* [Add “Mark media as sensitive” option](https://github.com/sk22/mastodon-android-fork/commits/feature/mark-media-as-sensitive)
|
||||
* [Add settings to hide replies and reposts from the timeline](https://github.com/sk22/mastodon-android-fork/commits/feature/filter-home-timeline) ([Pull request](https://github.com/mastodon/mastodon-android/pull/317))
|
||||
* [Follow and unfollow hashtags](https://github.com/sk22/mastodon-android-fork/commit/7d38f031f197aa6cefaf53e39d929538689c1e4e) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/233))
|
||||
* [Notification bell for posts](https://github.com/sk22/mastodon-android-fork/commit/b166ca705eb9169025ef32bbe6315b42491b57ea) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/81))
|
||||
* [Lists view (viewing only, for now)](https://github.com/sk22/mastodon-android-fork/commits/list-timeline-views) based on [@obstsalatschuessel](https://github.com/obstsalatschuessel)'s [Pull request](https://github.com/mastodon/mastodon-android/pull/286)
|
||||
|
||||
### Behavior
|
||||
|
||||
* [Make back button return to the home tab before exiting the app](https://github.com/sk22/mastodon-android-fork/tree/feature/back-returns-home) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/118))
|
||||
* [Always preserve content warnings when replying](https://github.com/sk22/mastodon-android-fork/tree/feature/always-preserve-cw) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/113))
|
||||
* [Display full image when adding image description](https://github.com/sk22/mastodon-android-fork/tree/feature/compose-image-description-full-image) ([Pull request](https://github.com/mastodon/mastodon-android/pull/182))
|
||||
* [Implement deleting and re-drafting](https://github.com/sk22/mastodon-android-fork/tree/feature/delete-redraft) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/21))
|
||||
* [Set spoiler height independently to content height](https://github.com/sk22/mastodon-android-fork/commits/spoiler-height-independent) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/166))
|
||||
* [Make back button return to the home tab before exiting the app](https://github.com/sk22/mastodon-android-fork/commits/feature/back-returns-home) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/118))
|
||||
* [Always preserve content warnings when replying](https://github.com/sk22/mastodon-android-fork/commits/feature/always-preserve-cw) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/113))
|
||||
* [Display full image when adding image description](https://github.com/sk22/mastodon-android-fork/commits/feature/compose-image-description-full-image) ([Pull request](https://github.com/mastodon/mastodon-android/pull/182))
|
||||
* [Set spoiler height independently to content height](https://github.com/sk22/mastodon-android-fork/commits/spoiler-height-independent) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/166))
|
||||
* [Custom extended footer redesign](https://github.com/sk22/mastodon-android-fork/commits/compact-extended-footer)
|
||||
* [Option to hide interaction numbers](https://github.com/sk22/mastodon-android-fork/commits/settings/hide-interaction-numbers)
|
||||
|
||||
### Installation
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId "org.joinmastodon.android.sk"
|
||||
minSdk 23
|
||||
targetSdk 33
|
||||
versionCode 30
|
||||
versionName "1.1.4+fork.30"
|
||||
versionCode 36
|
||||
versionName "1.1.4+fork.36"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
resConfigs "en", "ar-rSA", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES",
|
||||
"eu-rES", "fi-rFI", "fr-rFR", "gl-rES", "hr-rHR", "hy-rAM", "it-rIT", "iw-rIL",
|
||||
|
||||
@@ -7,6 +7,10 @@ public class GlobalUserPreferences{
|
||||
public static boolean playGifs;
|
||||
public static boolean useCustomTabs;
|
||||
public static boolean trueBlackTheme;
|
||||
public static boolean showReplies;
|
||||
public static boolean showBoosts;
|
||||
public static boolean loadNewPosts;
|
||||
public static boolean showInteractionCounts;
|
||||
public static ThemePreference theme;
|
||||
|
||||
private static SharedPreferences getPrefs(){
|
||||
@@ -18,6 +22,10 @@ public class GlobalUserPreferences{
|
||||
playGifs=prefs.getBoolean("playGifs", true);
|
||||
useCustomTabs=prefs.getBoolean("useCustomTabs", true);
|
||||
trueBlackTheme=prefs.getBoolean("trueBlackTheme", false);
|
||||
showReplies=prefs.getBoolean("showReplies", true);
|
||||
showBoosts=prefs.getBoolean("showBoosts", true);
|
||||
loadNewPosts=prefs.getBoolean("loadNewPosts", true);
|
||||
showInteractionCounts=prefs.getBoolean("showInteractionCounts", true);
|
||||
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
|
||||
}
|
||||
|
||||
@@ -25,7 +33,11 @@ public class GlobalUserPreferences{
|
||||
getPrefs().edit()
|
||||
.putBoolean("playGifs", playGifs)
|
||||
.putBoolean("useCustomTabs", useCustomTabs)
|
||||
.putBoolean("showReplies", showReplies)
|
||||
.putBoolean("showBoosts", showBoosts)
|
||||
.putBoolean("loadNewPosts", loadNewPosts)
|
||||
.putBoolean("trueBlackTheme", trueBlackTheme)
|
||||
.putBoolean("showInteractionCounts", showInteractionCounts)
|
||||
.putInt("theme", theme.ordinal())
|
||||
.apply();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import android.media.ExifInterface;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.joinmastodon.android.MastodonApp;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
@@ -48,6 +49,8 @@ public class ResizedImageRequestBody extends CountingRequestBody{
|
||||
}
|
||||
contentType=MastodonApp.context.getContentResolver().getType(uri);
|
||||
}
|
||||
if(TextUtils.isEmpty(contentType))
|
||||
contentType="image/jpeg";
|
||||
if(needResize(opts.outWidth, opts.outHeight) || needCrop(opts.outWidth, opts.outHeight)){
|
||||
Bitmap bitmap;
|
||||
if(Build.VERSION.SDK_INT>=28){
|
||||
|
||||
@@ -4,10 +4,10 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
|
||||
public class SetAccountFollowed extends MastodonAPIRequest<Relationship>{
|
||||
public SetAccountFollowed(String id, boolean followed, boolean showReblogs){
|
||||
public SetAccountFollowed(String id, boolean followed, boolean showReblogs, boolean notify){
|
||||
super(HttpMethod.POST, "/accounts/"+id+"/"+(followed ? "follow" : "unfollow"), Relationship.class);
|
||||
if(followed)
|
||||
setRequestBody(new Request(showReblogs, null));
|
||||
setRequestBody(new Request(showReblogs, notify));
|
||||
else
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.joinmastodon.android.api.requests.lists;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GetLists extends MastodonAPIRequest<List<ListTimeline>>{
|
||||
public GetLists() {
|
||||
super(HttpMethod.GET, "/lists", new TypeToken<>(){});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.api.requests.tags;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
|
||||
public class GetHashtag extends MastodonAPIRequest<Hashtag> {
|
||||
public GetHashtag(String name){
|
||||
super(HttpMethod.GET, "/tags/"+name, Hashtag.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.api.requests.tags;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
|
||||
public class SetHashtagFollowed extends MastodonAPIRequest<Hashtag>{
|
||||
public SetHashtagFollowed(String name, boolean followed){
|
||||
super(HttpMethod.POST, "/tags/"+name+"/"+(followed ? "follow" : "unfollow"), Hashtag.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.joinmastodon.android.api.requests.timelines;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GetListTimeline extends MastodonAPIRequest<List<Status>> {
|
||||
public GetListTimeline(String listID, String maxID, String minID, int limit, String sinceID) {
|
||||
super(HttpMethod.GET, "/timelines/list/"+listID, new TypeToken<>(){});
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(minID!=null)
|
||||
addQueryParameter("min_id", minID);
|
||||
if(limit>0)
|
||||
addQueryParameter("limit", ""+limit);
|
||||
if(sinceID!=null)
|
||||
addQueryParameter("since_id", sinceID);
|
||||
}
|
||||
}
|
||||
@@ -422,17 +422,17 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
outState.putStringArrayList("pollOptions", opts);
|
||||
outState.putInt("pollDuration", pollDuration);
|
||||
outState.putString("pollDurationStr", pollDurationStr);
|
||||
outState.putBoolean("hasSpoiler", hasSpoiler);
|
||||
if(!attachments.isEmpty()){
|
||||
ArrayList<Parcelable> serializedAttachments=new ArrayList<>(attachments.size());
|
||||
for(DraftMediaAttachment att:attachments){
|
||||
serializedAttachments.add(Parcels.wrap(att));
|
||||
}
|
||||
outState.putParcelableArrayList("attachments", serializedAttachments);
|
||||
}
|
||||
outState.putSerializable("visibility", statusVisibility);
|
||||
}
|
||||
outState.putBoolean("hasSpoiler", hasSpoiler);
|
||||
outState.putBoolean("sensitive", sensitive);
|
||||
if(!attachments.isEmpty()){
|
||||
ArrayList<Parcelable> serializedAttachments=new ArrayList<>(attachments.size());
|
||||
for(DraftMediaAttachment att:attachments){
|
||||
serializedAttachments.add(Parcels.wrap(att));
|
||||
}
|
||||
outState.putParcelableArrayList("attachments", serializedAttachments);
|
||||
}
|
||||
outState.putSerializable("visibility", statusVisibility);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -557,6 +557,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
da.serverAttachment=att;
|
||||
da.description=att.description;
|
||||
da.uri=Uri.parse(att.previewUrl);
|
||||
da.state=AttachmentUploadState.DONE;
|
||||
attachmentsView.addView(createMediaAttachmentView(da));
|
||||
attachments.add(da);
|
||||
}
|
||||
|
||||
@@ -2,23 +2,34 @@ package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.tags.GetHashtag;
|
||||
import org.joinmastodon.android.api.requests.tags.SetHashtagFollowed;
|
||||
import org.joinmastodon.android.api.requests.timelines.GetHashtagTimeline;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class HashtagTimelineFragment extends StatusListFragment{
|
||||
private String hashtag;
|
||||
private boolean following;
|
||||
private ImageButton fab;
|
||||
private MenuItem followButton;
|
||||
|
||||
public HashtagTimelineFragment(){
|
||||
setListLayoutId(R.layout.recycler_fragment_with_fab);
|
||||
@@ -27,10 +38,61 @@ public class HashtagTimelineFragment extends StatusListFragment{
|
||||
@Override
|
||||
public void onAttach(Activity activity){
|
||||
super.onAttach(activity);
|
||||
hashtag=getArguments().getString("hashtag");
|
||||
updateTitle(getArguments().getString("hashtag"));
|
||||
following=getArguments().getBoolean("following", false);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
private void updateTitle(String hashtagName) {
|
||||
hashtag = hashtagName;
|
||||
setTitle('#'+hashtag);
|
||||
}
|
||||
|
||||
private void updateFollowingState(boolean newFollowing) {
|
||||
this.following = newFollowing;
|
||||
followButton.setTitle(getString(newFollowing ? R.string.unfollow_user : R.string.follow_user, "#" + hashtag));
|
||||
followButton.setIcon(newFollowing ? R.drawable.ic_fluent_person_delete_24_filled : R.drawable.ic_fluent_person_add_24_regular);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.hashtag_timeline, menu);
|
||||
followButton = menu.findItem(R.id.follow_hashtag);
|
||||
updateFollowingState(following);
|
||||
|
||||
followButton.setOnMenuItemClickListener(i -> {
|
||||
updateFollowingState(!following);
|
||||
new SetHashtagFollowed(hashtag, following).setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(Hashtag i) {
|
||||
updateFollowingState(i.following);
|
||||
Toast.makeText(getActivity(), getString(i.following ? R.string.followed_user : R.string.unfollowed_user, "#" + i.name), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
error.showToast(getActivity());
|
||||
updateFollowingState(!following);
|
||||
}
|
||||
}).exec(accountID);
|
||||
return true;
|
||||
});
|
||||
|
||||
new GetHashtag(hashtag).setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(Hashtag hashtag) {
|
||||
updateTitle(hashtag.name);
|
||||
updateFollowingState(hashtag.following);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
}).exec(accountID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest=new GetHashtagTimeline(hashtag, offset==0 ? null : getMaxID(), null, count)
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.widget.Toolbar;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
@@ -73,6 +74,13 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||
loadData();
|
||||
}
|
||||
|
||||
private List<Status> filterPosts(List<Status> items) {
|
||||
return items.stream().filter(i ->
|
||||
(GlobalUserPreferences.showReplies || i.inReplyToId == null) &&
|
||||
(GlobalUserPreferences.showBoosts || i.reblog == null)
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
AccountSessionManager.getInstance()
|
||||
@@ -82,7 +90,8 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||
public void onSuccess(CacheablePaginatedResponse<List<Status>> result){
|
||||
if(getActivity()==null)
|
||||
return;
|
||||
onDataLoaded(result.items, !result.items.isEmpty());
|
||||
List<Status> filteredItems = filterPosts(result.items);
|
||||
onDataLoaded(filteredItems, !result.items.isEmpty());
|
||||
maxID=result.maxID;
|
||||
if(result.isFromCache())
|
||||
loadNewPosts();
|
||||
@@ -153,6 +162,7 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||
}
|
||||
|
||||
private void loadNewPosts(){
|
||||
if (!GlobalUserPreferences.loadNewPosts) return;
|
||||
dataLoading=true;
|
||||
// The idea here is that we request the timeline such that if there are fewer than `limit` posts,
|
||||
// we'll get the currently topmost post as last in the response. This way we know there's no gap
|
||||
@@ -164,6 +174,7 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||
public void onSuccess(List<Status> result){
|
||||
currentRequest=null;
|
||||
dataLoading=false;
|
||||
result = filterPosts(result);
|
||||
if(result.isEmpty() || getActivity()==null)
|
||||
return;
|
||||
Status last=result.get(result.size()-1);
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.media.MediaRouter;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.timelines.GetListTimeline;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
|
||||
public class ListTimelineFragment extends StatusListFragment {
|
||||
private String listID;
|
||||
private String listTitle;
|
||||
private ImageButton fab;
|
||||
|
||||
public ListTimelineFragment() {
|
||||
setListLayoutId(R.layout.recycler_fragment_with_fab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity){
|
||||
super.onAttach(activity);
|
||||
listID=getArguments().getString("listID");
|
||||
listTitle=getArguments().getString("listTitle");
|
||||
setTitle(listTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count) {
|
||||
currentRequest=new GetListTimeline(listID, offset==0 ? null : getMaxID(), null, count, null)
|
||||
.setCallback(new SimpleCallback<>(this) {
|
||||
@Override
|
||||
public void onSuccess(List<Status> result) {
|
||||
onDataLoaded(result, !result.isEmpty());
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShown() {
|
||||
super.onShown();
|
||||
if(!getArguments().getBoolean("noAutoLoad") && !loaded && !dataLoading)
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
fab=view.findViewById(R.id.fab);
|
||||
fab.setOnClickListener(this::onFabClick);
|
||||
}
|
||||
|
||||
private void onFabClick(View v){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putString("prefilledText", listID+' ');
|
||||
Nav.go(getActivity(), ComposeFragment.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSetFabBottomInset(int inset) {
|
||||
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(24)+inset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.lists.GetLists;
|
||||
import org.joinmastodon.android.fragments.ScrollableToTop;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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 ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> implements ScrollableToTop {
|
||||
private String accountId;
|
||||
|
||||
public ListTimelinesFragment() {
|
||||
super(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
accountId=getArguments().getString("account");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest=new GetLists()
|
||||
.setCallback(new SimpleCallback<>(this) {
|
||||
@Override
|
||||
public void onSuccess(List<ListTimeline> result) {
|
||||
onDataLoaded(result, false);
|
||||
}
|
||||
})
|
||||
.exec(accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecyclerView.Adapter getAdapter() {
|
||||
return new ListsAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrollToTop() {
|
||||
smoothScrollRecyclerViewToTop(list);
|
||||
}
|
||||
|
||||
private class ListsAdapter extends RecyclerView.Adapter<ListViewHolder>{
|
||||
@NonNull
|
||||
@Override
|
||||
public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||
return new ListViewHolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
|
||||
holder.bind(data.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
}
|
||||
|
||||
private class ListViewHolder extends BindableViewHolder<ListTimeline> implements UsableRecyclerView.Clickable{
|
||||
private final TextView title;
|
||||
|
||||
public ListViewHolder(){
|
||||
super(getActivity(), R.layout.item_list_timeline, list);
|
||||
title=findViewById(R.id.title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(ListTimeline item) {
|
||||
title.setText(item.title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
UiUtils.openListTimeline(getActivity(), accountId, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
private CoverImageView cover;
|
||||
private View avatarBorder;
|
||||
private TextView name, username, bio, followersCount, followersLabel, followingCount, followingLabel, postsCount, postsLabel;
|
||||
private ProgressBarButton actionButton;
|
||||
private ProgressBarButton actionButton, notifyButton;
|
||||
private ViewPager2 pager;
|
||||
private NestedRecyclerScrollView scrollView;
|
||||
private AccountTimelineFragment postsFragment, postsWithRepliesFragment, pinnedPostsFragment, mediaFragment;
|
||||
@@ -109,7 +109,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
private float titleTransY;
|
||||
private View postsBtn, followersBtn, followingBtn;
|
||||
private EditText nameEdit, bioEdit;
|
||||
private ProgressBar actionProgress;
|
||||
private ProgressBar actionProgress, notifyProgress;
|
||||
private FrameLayout[] tabViews;
|
||||
private TabLayoutMediator tabLayoutMediator;
|
||||
private TextView followsYouView;
|
||||
@@ -181,6 +181,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
postsLabel=content.findViewById(R.id.posts_label);
|
||||
postsBtn=content.findViewById(R.id.posts_btn);
|
||||
actionButton=content.findViewById(R.id.profile_action_btn);
|
||||
notifyButton=content.findViewById(R.id.notify_btn);
|
||||
pager=content.findViewById(R.id.pager);
|
||||
scrollView=content.findViewById(R.id.scroller);
|
||||
tabbar=content.findViewById(R.id.tabbar);
|
||||
@@ -188,6 +189,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
nameEdit=content.findViewById(R.id.name_edit);
|
||||
bioEdit=content.findViewById(R.id.bio_edit);
|
||||
actionProgress=content.findViewById(R.id.action_progress);
|
||||
notifyProgress=content.findViewById(R.id.notify_progress);
|
||||
fab=content.findViewById(R.id.fab);
|
||||
followsYouView=content.findViewById(R.id.follows_you);
|
||||
|
||||
@@ -258,6 +260,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
});
|
||||
|
||||
actionButton.setOnClickListener(this::onActionButtonClick);
|
||||
notifyButton.setOnClickListener(this::onNotifyButtonClick);
|
||||
avatar.setOnClickListener(this::onAvatarClick);
|
||||
cover.setOnClickListener(this::onCoverClick);
|
||||
refreshLayout.setOnRefreshListener(this);
|
||||
@@ -458,6 +461,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
UiUtils.loadCustomEmojiInTextView(name);
|
||||
UiUtils.loadCustomEmojiInTextView(bio);
|
||||
|
||||
notifyButton.setVisibility(View.GONE);
|
||||
if(AccountSessionManager.getInstance().isSelf(accountID, account)){
|
||||
actionButton.setText(R.string.edit_profile);
|
||||
}else{
|
||||
@@ -577,7 +581,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
updateRelationship();
|
||||
});
|
||||
}else if(id==R.id.hide_boosts){
|
||||
new SetAccountFollowed(account.id, true, !relationship.showingReblogs)
|
||||
new SetAccountFollowed(account.id, true, !relationship.showingReblogs, relationship.notifying)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
@@ -622,9 +626,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
private void updateRelationship(){
|
||||
invalidateOptionsMenu();
|
||||
actionButton.setVisibility(View.VISIBLE);
|
||||
notifyButton.setVisibility(relationship.following ? View.VISIBLE : View.GONE);
|
||||
UiUtils.setRelationshipToActionButton(relationship, actionButton);
|
||||
UiUtils.setRelationshipToActionButton(relationship, notifyButton, true);
|
||||
actionProgress.setIndeterminateTintList(actionButton.getTextColors());
|
||||
notifyProgress.setIndeterminateTintList(notifyButton.getTextColors());
|
||||
followsYouView.setVisibility(relationship.followedBy ? View.VISIBLE : View.GONE);
|
||||
notifyButton.setSelected(relationship.notifying);
|
||||
notifyButton.setContentDescription(getString(relationship.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username));
|
||||
}
|
||||
|
||||
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
|
||||
@@ -691,6 +700,12 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
actionButton.setClickable(!visible);
|
||||
}
|
||||
|
||||
private void setNotifyProgressVisible(boolean visible){
|
||||
notifyButton.setTextVisible(!visible);
|
||||
notifyProgress.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
notifyButton.setClickable(!visible);
|
||||
}
|
||||
|
||||
private void loadAccountInfoAndEnterEditMode(){
|
||||
if(editModeLoading)
|
||||
return;
|
||||
@@ -859,6 +874,10 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
return Collections.singletonList(att);
|
||||
}
|
||||
|
||||
private void onNotifyButtonClick(View v) {
|
||||
UiUtils.performToggleAccountNotifications(getActivity(), account, accountID, relationship, actionButton, this::setNotifyProgressVisible, this::updateRelationship);
|
||||
}
|
||||
|
||||
private void onAvatarClick(View v){
|
||||
if(isInEditMode){
|
||||
startImagePicker(AVATAR_RESULT);
|
||||
|
||||
@@ -104,6 +104,24 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
GlobalUserPreferences.useCustomTabs=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_show_interaction_counts, R.drawable.ic_fluent_number_row_24_regular, GlobalUserPreferences.showInteractionCounts, i->{
|
||||
GlobalUserPreferences.showInteractionCounts=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
|
||||
items.add(new HeaderItem(R.string.home_timeline));
|
||||
items.add(new SwitchItem(R.string.settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
||||
GlobalUserPreferences.showReplies=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_show_boosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, GlobalUserPreferences.showBoosts, i->{
|
||||
GlobalUserPreferences.showBoosts=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_load_new_posts, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.loadNewPosts, i->{
|
||||
GlobalUserPreferences.loadNewPosts=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
|
||||
items.add(new HeaderItem(R.string.settings_notifications));
|
||||
items.add(notificationPolicyItem=new NotificationPolicyItem());
|
||||
@@ -115,7 +133,6 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
|
||||
items.add(new HeaderItem(R.string.settings_boring));
|
||||
items.add(new TextItem(R.string.settings_account, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit")));
|
||||
items.add(new TextItem(R.string.settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/mastodon/mastodon-android")));
|
||||
items.add(new TextItem(R.string.settings_tos, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")));
|
||||
items.add(new TextItem(R.string.settings_privacy_policy, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")));
|
||||
|
||||
@@ -124,6 +141,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
checkForUpdateItem = new TextItem(R.string.check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates);
|
||||
items.add(checkForUpdateItem);
|
||||
}
|
||||
items.add(new TextItem(R.string.settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/mastodon/mastodon-android")));
|
||||
items.add(new TextItem(R.string.settings_clear_cache, this::clearImageCache));
|
||||
items.add(new TextItem(R.string.log_out, this::confirmLogOut));
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ public abstract class BaseAccountListFragment extends BaseRecyclerFragment<BaseA
|
||||
bindRelationship();
|
||||
});
|
||||
}else if(id==R.id.hide_boosts){
|
||||
new SetAccountFollowed(account.id, true, !relationship.showingReblogs)
|
||||
new SetAccountFollowed(account.id, true, !relationship.showingReblogs, relationship.notifying)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
|
||||
@@ -19,6 +19,7 @@ import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.ScrollableToTop;
|
||||
import org.joinmastodon.android.fragments.ListTimelinesFragment;
|
||||
import org.joinmastodon.android.ui.SimpleViewHolder;
|
||||
import org.joinmastodon.android.ui.tabs.TabLayout;
|
||||
import org.joinmastodon.android.ui.tabs.TabLayoutMediator;
|
||||
@@ -52,6 +53,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
private SearchFragment searchFragment;
|
||||
private LocalTimelineFragment localTimelineFragment;
|
||||
private FederatedTimelineFragment federatedTimelineFragment;
|
||||
private ListTimelinesFragment listTimelinesFragment;
|
||||
|
||||
private String accountID;
|
||||
private Runnable searchDebouncer=this::onSearchChangedDebounced;
|
||||
@@ -73,7 +75,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
tabLayout=view.findViewById(R.id.tabbar);
|
||||
pager=view.findViewById(R.id.pager);
|
||||
|
||||
tabViews=new FrameLayout[6];
|
||||
tabViews=new FrameLayout[7];
|
||||
for(int i=0;i<tabViews.length;i++){
|
||||
FrameLayout tabView=new FrameLayout(getActivity());
|
||||
tabView.setId(switch(i){
|
||||
@@ -83,6 +85,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
case 3 -> R.id.discover_posts;
|
||||
case 4 -> R.id.discover_news;
|
||||
case 5 -> R.id.discover_users;
|
||||
case 6 -> R.id.discover_lists;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+i);
|
||||
});
|
||||
tabView.setVisibility(View.GONE);
|
||||
@@ -131,6 +134,9 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
federatedTimelineFragment=new FederatedTimelineFragment();
|
||||
federatedTimelineFragment.setArguments(args);
|
||||
|
||||
listTimelinesFragment=new ListTimelinesFragment();
|
||||
listTimelinesFragment.setArguments(args);
|
||||
|
||||
getChildFragmentManager().beginTransaction()
|
||||
.add(R.id.discover_posts, postsFragment)
|
||||
.add(R.id.discover_local_timeline, localTimelineFragment)
|
||||
@@ -138,6 +144,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
.add(R.id.discover_hashtags, hashtagsFragment)
|
||||
.add(R.id.discover_news, newsFragment)
|
||||
.add(R.id.discover_users, accountsFragment)
|
||||
.add(R.id.discover_lists, listTimelinesFragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@@ -151,6 +158,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
case 3 -> R.string.posts;
|
||||
case 4 -> R.string.news;
|
||||
case 5 -> R.string.for_you;
|
||||
case 6 -> R.string.list_timelines;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+position);
|
||||
});
|
||||
tab.view.textView.setAllCaps(true);
|
||||
@@ -279,6 +287,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
case 3 -> postsFragment;
|
||||
case 4 -> newsFragment;
|
||||
case 5 -> accountsFragment;
|
||||
case 6 -> listTimelinesFragment;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+page);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -91,6 +91,8 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
@Override
|
||||
public void onItemClick(String id){
|
||||
SearchResult res=getResultByID(id);
|
||||
if(res==null)
|
||||
return;
|
||||
switch(res.type){
|
||||
case ACCOUNT -> {
|
||||
Bundle args=new Bundle();
|
||||
@@ -98,7 +100,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
args.putParcelable("profileAccount", Parcels.wrap(res.account));
|
||||
Nav.go(getActivity(), ProfileFragment.class, args);
|
||||
}
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag.name);
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag.name, res.hashtag.following);
|
||||
case STATUS -> {
|
||||
Status status=res.status.getContentStatus();
|
||||
Bundle args=new Bundle();
|
||||
|
||||
@@ -107,7 +107,7 @@ public class TrendingHashtagsFragment extends BaseRecyclerFragment<Hashtag> impl
|
||||
|
||||
@Override
|
||||
public void onClick(){
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, item.name);
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, item.name, item.following);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,6 @@ public class SignupFragment extends AppKitFragment{
|
||||
@Override
|
||||
public void onSuccess(Token result){
|
||||
progressDialog.dismiss();
|
||||
progressDialog=null;
|
||||
Account fakeAccount=new Account();
|
||||
fakeAccount.acct=fakeAccount.username=username;
|
||||
fakeAccount.id="tmp"+System.currentTimeMillis();
|
||||
@@ -238,7 +237,6 @@ public class SignupFragment extends AppKitFragment{
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
progressDialog.dismiss();
|
||||
progressDialog=null;
|
||||
}
|
||||
})
|
||||
.exec(instance.uri, apiToken);
|
||||
@@ -255,9 +253,11 @@ public class SignupFragment extends AppKitFragment{
|
||||
}
|
||||
|
||||
private void showProgressDialog(){
|
||||
progressDialog=new ProgressDialog(getActivity());
|
||||
progressDialog.setMessage(getString(R.string.loading));
|
||||
progressDialog.setCancelable(false);
|
||||
if(progressDialog==null){
|
||||
progressDialog=new ProgressDialog(getActivity());
|
||||
progressDialog.setMessage(getString(R.string.loading));
|
||||
progressDialog.setCancelable(false);
|
||||
}
|
||||
progressDialog.show();
|
||||
}
|
||||
|
||||
@@ -280,7 +280,6 @@ public class SignupFragment extends AppKitFragment{
|
||||
if(submitAfterGettingToken){
|
||||
submitAfterGettingToken=false;
|
||||
progressDialog.dismiss();
|
||||
progressDialog=null;
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
}
|
||||
@@ -307,7 +306,6 @@ public class SignupFragment extends AppKitFragment{
|
||||
if(submitAfterGettingToken){
|
||||
submitAfterGettingToken=false;
|
||||
progressDialog.dismiss();
|
||||
progressDialog=null;
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ public class ReportDoneFragment extends MastodonToolbarFragment{
|
||||
}
|
||||
|
||||
private void onUnfollowClick(){
|
||||
new SetAccountFollowed(reportAccount.id, false, false)
|
||||
new SetAccountFollowed(reportAccount.id, false, false, false)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
|
||||
@@ -11,6 +11,7 @@ public class Hashtag extends BaseModel{
|
||||
public String name;
|
||||
@RequiredField
|
||||
public String url;
|
||||
public boolean following;
|
||||
public List<History> history;
|
||||
|
||||
@Override
|
||||
@@ -18,6 +19,7 @@ public class Hashtag extends BaseModel{
|
||||
return "Hashtag{"+
|
||||
"name='"+name+'\''+
|
||||
", url='"+url+'\''+
|
||||
", following="+following+
|
||||
", history="+history+
|
||||
'}';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
import org.parceler.Parcel;
|
||||
|
||||
@Parcel
|
||||
public class ListTimeline extends BaseModel {
|
||||
@RequiredField
|
||||
public String id;
|
||||
@RequiredField
|
||||
public String title;
|
||||
@RequiredField
|
||||
public RepliesPolicy repliesPolicy;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "List{" +
|
||||
"id='" + id + '\'' +
|
||||
", title='" + title + '\'' +
|
||||
", repliesPolicy=" + repliesPolicy +
|
||||
'}';
|
||||
}
|
||||
|
||||
public enum RepliesPolicy{
|
||||
@SerializedName("followed")
|
||||
FOLLOWED,
|
||||
@SerializedName("list")
|
||||
LIST,
|
||||
@SerializedName("none")
|
||||
NONE
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.TypefaceSpan;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
@@ -45,18 +47,20 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
|
||||
}
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<ExtendedFooterStatusDisplayItem>{
|
||||
private final TextView time, favoritesCount, reblogsCount, lastEditTime;
|
||||
private final View favorites, reblogs, editHistory;
|
||||
private final TextView time;
|
||||
private final Button favorites, reblogs, editHistory, applicationName;
|
||||
private final ImageView visibility;
|
||||
private final Context context;
|
||||
|
||||
public Holder(Context context, ViewGroup parent){
|
||||
super(context, R.layout.display_item_extended_footer, parent);
|
||||
this.context = context;
|
||||
reblogs=findViewById(R.id.reblogs);
|
||||
favorites=findViewById(R.id.favorites);
|
||||
editHistory=findViewById(R.id.edit_history);
|
||||
applicationName=findViewById(R.id.application_name);
|
||||
visibility=findViewById(R.id.visibility);
|
||||
time=findViewById(R.id.timestamp);
|
||||
favoritesCount=findViewById(R.id.favorites_count);
|
||||
reblogsCount=findViewById(R.id.reblogs_count);
|
||||
lastEditTime=findViewById(R.id.last_edited);
|
||||
|
||||
reblogs.setOnClickListener(v->startAccountListFragment(StatusReblogsListFragment.class));
|
||||
favorites.setOnClickListener(v->startAccountListFragment(StatusFavoritesListFragment.class));
|
||||
@@ -67,20 +71,35 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
|
||||
@Override
|
||||
public void onBind(ExtendedFooterStatusDisplayItem item){
|
||||
Status s=item.status;
|
||||
favoritesCount.setText(String.format("%,d", s.favouritesCount));
|
||||
reblogsCount.setText(String.format("%,d", s.reblogsCount));
|
||||
favorites.setText(context.getResources().getQuantityString(R.plurals.x_favorites, (int)(s.favouritesCount%1000), s.favouritesCount));
|
||||
reblogs.setText(context.getResources().getQuantityString(R.plurals.x_reblogs, (int)(s.reblogsCount%1000), s.reblogsCount));
|
||||
if(s.editedAt!=null){
|
||||
editHistory.setVisibility(View.VISIBLE);
|
||||
lastEditTime.setText(item.parentFragment.getString(R.string.last_edit_at_x, UiUtils.formatRelativeTimestampAsMinutesAgo(itemView.getContext(), s.editedAt)));
|
||||
editHistory.setText(UiUtils.formatRelativeTimestampAsMinutesAgo(itemView.getContext(), s.editedAt));
|
||||
}else{
|
||||
editHistory.setVisibility(View.GONE);
|
||||
}
|
||||
String timeStr=TIME_FORMATTER.format(item.status.createdAt.atZone(ZoneId.systemDefault()));
|
||||
if(item.status.application!=null && !TextUtils.isEmpty(item.status.application.name)){
|
||||
time.setText(item.parentFragment.getString(R.string.timestamp_via_app, timeStr, item.status.application.name));
|
||||
}else{
|
||||
|
||||
if (item.status.application!=null && !TextUtils.isEmpty(item.status.application.name)) {
|
||||
time.setText(item.parentFragment.getString(R.string.timestamp_via_app, timeStr, ""));
|
||||
applicationName.setText(item.status.application.name);
|
||||
if (item.status.application.website != null && item.status.application.website.toLowerCase().startsWith("https://")) {
|
||||
applicationName.setOnClickListener(e -> UiUtils.openURL(context, null, item.status.application.website));
|
||||
} else {
|
||||
applicationName.setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
time.setText(timeStr);
|
||||
applicationName.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
visibility.setImageResource(switch (s.visibility) {
|
||||
case PUBLIC -> R.drawable.ic_fluent_earth_20_regular;
|
||||
case UNLISTED -> R.drawable.ic_fluent_people_20_regular;
|
||||
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_20_regular;
|
||||
case DIRECT -> R.drawable.ic_at_symbol;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,6 +11,7 @@ import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
@@ -98,7 +99,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
}
|
||||
|
||||
private void bindButton(TextView btn, long count){
|
||||
if(count>0 && !item.hideCounts){
|
||||
if(GlobalUserPreferences.showInteractionCounts && count>0 && !item.hideCounts){
|
||||
btn.setText(DecimalFormat.getIntegerInstance().format(count));
|
||||
btn.setCompoundDrawablePadding(V.dp(8));
|
||||
}else{
|
||||
|
||||
@@ -158,7 +158,7 @@ public abstract class StatusDisplayItem{
|
||||
}
|
||||
|
||||
public Holder(Context context, int layout, ViewGroup parent){
|
||||
super(context, layout, parent);
|
||||
super(context, layout, parent);
|
||||
}
|
||||
|
||||
public String getItemID(){
|
||||
|
||||
@@ -34,7 +34,7 @@ public class LinkSpan extends CharacterStyle {
|
||||
switch(getType()){
|
||||
case URL -> UiUtils.openURL(context, accountID, link);
|
||||
case MENTION -> UiUtils.openProfileByID(context, accountID, link);
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(context, accountID, link);
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(context, accountID, link, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,10 +50,12 @@ import org.joinmastodon.android.events.StatusUnpinnedEvent;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.ListTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
@@ -80,6 +82,7 @@ import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.browser.customtabs.CustomTabsIntent;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
@@ -309,13 +312,22 @@ public class UiUtils{
|
||||
Nav.go((Activity)context, ProfileFragment.class, args);
|
||||
}
|
||||
|
||||
public static void openHashtagTimeline(Context context, String accountID, String hashtag){
|
||||
public static void openHashtagTimeline(Context context, String accountID, String hashtag, @Nullable Boolean following){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putString("hashtag", hashtag);
|
||||
if (following != null) args.putBoolean("following", following);
|
||||
Nav.go((Activity)context, HashtagTimelineFragment.class, args);
|
||||
}
|
||||
|
||||
public static void openListTimeline(Context context, String accountID, ListTimeline list){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putString("listID", list.id);
|
||||
args.putString("listTitle", list.title);
|
||||
Nav.go((Activity)context, ListTimelineFragment.class, args);
|
||||
}
|
||||
|
||||
public static void showConfirmationAlert(Context context, @StringRes int title, @StringRes int message, @StringRes int confirmButton, Runnable onConfirmed){
|
||||
showConfirmationAlert(context, context.getString(title), context.getString(message), context.getString(confirmButton), onConfirmed);
|
||||
}
|
||||
@@ -496,6 +508,11 @@ public class UiUtils{
|
||||
}
|
||||
|
||||
public static void setRelationshipToActionButton(Relationship relationship, Button button){
|
||||
setRelationshipToActionButton(relationship, button, false);
|
||||
}
|
||||
|
||||
public static void setRelationshipToActionButton(Relationship relationship, Button button, boolean keepText){
|
||||
CharSequence textBefore = keepText ? button.getText() : null;
|
||||
boolean secondaryStyle;
|
||||
if(relationship.blocking){
|
||||
button.setText(R.string.button_blocked);
|
||||
@@ -514,6 +531,8 @@ public class UiUtils{
|
||||
secondaryStyle=true;
|
||||
}
|
||||
|
||||
if (keepText) button.setText(textBefore);
|
||||
|
||||
button.setEnabled(!relationship.blockedBy);
|
||||
int attr=secondaryStyle ? R.attr.secondaryButtonStyle : android.R.attr.buttonStyle;
|
||||
TypedArray ta=button.getContext().obtainStyledAttributes(new int[]{attr});
|
||||
@@ -530,6 +549,25 @@ public class UiUtils{
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
public static void performToggleAccountNotifications(Activity activity, Account account, String accountID, Relationship relationship, Button button, Consumer<Boolean> progressCallback, Consumer<Relationship> resultCallback) {
|
||||
progressCallback.accept(true);
|
||||
new SetAccountFollowed(account.id, true, relationship.showingReblogs, !relationship.notifying)
|
||||
.setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(Relationship result) {
|
||||
resultCallback.accept(result);
|
||||
progressCallback.accept(false);
|
||||
Toast.makeText(activity, activity.getString(result.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
progressCallback.accept(false);
|
||||
error.showToast(activity);
|
||||
}
|
||||
}).exec(accountID);
|
||||
}
|
||||
|
||||
public static void performAccountAction(Activity activity, Account account, String accountID, Relationship relationship, Button button, Consumer<Boolean> progressCallback, Consumer<Relationship> resultCallback){
|
||||
if(relationship.blocking){
|
||||
confirmToggleBlockUser(activity, accountID, account, true, resultCallback);
|
||||
@@ -537,7 +575,7 @@ public class UiUtils{
|
||||
confirmToggleMuteUser(activity, accountID, account, true, resultCallback);
|
||||
}else{
|
||||
progressCallback.accept(true);
|
||||
new SetAccountFollowed(account.id, !relationship.following && !relationship.requested, true)
|
||||
new SetAccountFollowed(account.id, !relationship.following && !relationship.requested, true, false)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
@@ -643,10 +681,10 @@ public class UiUtils{
|
||||
return GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.DARK;
|
||||
}
|
||||
|
||||
public static void openURL(Context context, String accountID, String url){
|
||||
public static void openURL(Context context, @Nullable String accountID, String url){
|
||||
Uri uri=Uri.parse(url);
|
||||
String accountDomain=AccountSessionManager.getInstance().getAccount(accountID).domain;
|
||||
if("https".equals(uri.getScheme()) && accountDomain.equalsIgnoreCase(uri.getAuthority())){
|
||||
String accountDomain=accountID != null ? AccountSessionManager.getInstance().getAccount(accountID).domain : null;
|
||||
if(accountDomain!=null && "https".equals(uri.getScheme()) && accountDomain.equalsIgnoreCase(uri.getAuthority())){
|
||||
List<String> path=uri.getPathSegments();
|
||||
// Match URLs like https://mastodon.social/@Gargron/108132679274083591
|
||||
if(path.size()==2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$")){
|
||||
|
||||
@@ -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="M9.042 19.003h5.916c-0.238 1.418-1.472 2.498-2.958 2.498-1.486 0-2.72-1.08-2.958-2.498zm2.958-17c4.142 0 7.5 3.359 7.5 7.5v4l1.418 3.16c0.055 0.122 0.084 0.254 0.084 0.389 0 0.524-0.426 0.95-0.95 0.95h-16.1c-0.134 0-0.266-0.029-0.388-0.083-0.479-0.215-0.693-0.777-0.479-1.256l1.415-3.16V9.49l0.005-0.25C4.644 5.211 7.955 2.004 12 2.004z" 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="M12 1.996c4.05 0 7.357 3.195 7.496 7.25l0.004 0.25v4.097l1.38 3.156c0.07 0.158 0.105 0.329 0.105 0.5 0 0.691-0.56 1.25-1.25 1.25L15 18.502c0 1.657-1.343 3-3 3-1.598 0-2.904-1.249-2.995-2.823L9 18.499H4.275c-0.171 0-0.34-0.034-0.498-0.103-0.633-0.275-0.924-1.01-0.649-1.644L4.5 13.594V9.496c0-4.155 3.352-7.5 7.5-7.5zM13.5 18.5l-3 0.002c0 0.829 0.672 1.5 1.5 1.5 0.78 0 1.42-0.595 1.493-1.355L13.5 18.5zM12 3.496c-3.32 0-6 2.674-6 6v4.41L4.656 17h14.697L18 13.907V9.509l-0.003-0.225C17.885 6.05 15.242 3.496 12 3.496z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--~ Copyright (c) 2022. ~ Microsoft Corporation. All rights reserved.-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_fluent_alert_24_filled" android:state_activated="true"/>
|
||||
<item android:drawable="@drawable/ic_fluent_alert_24_filled" android:state_checked="true"/>
|
||||
<item android:drawable="@drawable/ic_fluent_alert_24_filled" android:state_selected="true"/>
|
||||
<item android:drawable="@drawable/ic_fluent_alert_24_regular"/>
|
||||
</selector>
|
||||
@@ -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="M16.5 6.671c0.116 0 0.223 0.04 0.308 0.106l0.067 0.064 0.017 0.02C17.585 7.719 18 8.81 18 10c0 2.689-2.122 4.882-4.783 4.995L13 15H7c-0.102 0-0.203-0.003-0.303-0.009l1.657 1.655c0.173 0.174 0.192 0.443 0.057 0.638l-0.057 0.07C8.18 17.527 7.91 17.546 7.716 17.41l-0.07-0.057-2.5-2.5C4.973 14.68 4.954 14.41 5.09 14.216l0.057-0.07 2.5-2.5c0.196-0.195 0.512-0.195 0.708 0 0.173 0.174 0.192 0.443 0.057 0.638l-0.057 0.07-1.637 1.636 0.14 0.008L7 14h6c2.21 0 4-1.79 4-4 0-0.954-0.334-1.829-0.89-2.516C16.04 7.399 16 7.29 16 7.17c0-0.276 0.224-0.5 0.5-0.5zm-4.854-4.024c0.174-0.174 0.443-0.193 0.638-0.058l0.07 0.058 2.5 2.5 0.057 0.069c0.119 0.17 0.119 0.398 0 0.568l-0.057 0.07-2.5 2.5-0.07 0.057c-0.17 0.119-0.398 0.119-0.568 0l-0.07-0.057-0.057-0.07c-0.119-0.17-0.119-0.398 0-0.568l0.057-0.07 1.637-1.636-0.14-0.007L13 6H7c-2.21 0-4 1.79-4 4 0 0.956 0.336 1.834 0.895 2.522C3.96 12.606 4 12.714 4 12.832c0 0.275-0.224 0.5-0.5 0.5-0.167 0-0.315-0.083-0.406-0.208C2.41 12.268 2 11.182 2 10c0-2.689 2.122-4.882 4.783-4.995L7 5h6c0.102 0 0.203 0.003 0.303 0.009l-1.657-1.656-0.057-0.069c-0.135-0.195-0.116-0.464 0.057-0.637z" 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="M4.209 10.733c-0.286 0.3-0.274 0.774 0.026 1.06 0.3 0.286 0.774 0.274 1.06-0.026l5.954-6.251V20.25c0 0.414 0.336 0.75 0.75 0.75 0.415 0 0.75-0.336 0.75-0.75V5.516l5.955 6.251c0.286 0.3 0.76 0.312 1.06 0.026 0.3-0.286 0.312-0.76 0.027-1.06l-7.067-7.42c-0.161-0.168-0.367-0.268-0.58-0.3C12.097 3.006 12.049 3 11.999 3c-0.05 0-0.098 0.005-0.145 0.014-0.213 0.031-0.418 0.131-0.578 0.3l-7.067 7.419z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M2 10c0-4.418 3.582-8 8-8 4.419 0 8 3.582 8 8 0 4.419-3.581 8-8 8-4.418 0-8-3.581-8-8zm8-7C9.915 3 9.83 3.002 9.745 3.005c0.118 0.222 0.253 0.504 0.373 0.823 0.28 0.746 0.527 1.817 0.085 2.758C9.799 7.446 9.106 7.67 8.57 7.808L8.474 7.833c-0.506 0.13-0.755 0.194-0.93 0.46-0.17 0.257-0.129 0.574 0.037 1.113L7.619 9.53c0.067 0.211 0.144 0.457 0.184 0.688 0.05 0.286 0.06 0.636-0.113 0.97C7.51 11.53 7.276 11.762 7 11.912c-0.26 0.142-0.533 0.197-0.747 0.235l-0.088 0.015c-0.407 0.072-0.645 0.113-0.867 0.351-0.177 0.19-0.279 0.508-0.336 0.941-0.024 0.178-0.038 0.355-0.053 0.534l-0.007 0.095c-0.017 0.199-0.037 0.419-0.079 0.605l-0.005 0.02C6.1 16.116 7.947 17 10 17c1.35 0 2.612-0.383 3.682-1.045-0.086-0.086-0.181-0.189-0.275-0.307-0.271-0.34-0.609-0.909-0.492-1.57 0.056-0.313 0.226-0.581 0.397-0.794 0.175-0.216 0.386-0.417 0.576-0.592l0.128-0.117c0.146-0.133 0.273-0.25 0.382-0.363 0.147-0.154 0.191-0.237 0.2-0.263 0.068-0.226-0.013-0.404-0.126-0.492-0.094-0.073-0.295-0.142-0.61 0.058-0.12 0.075-0.228 0.141-0.323 0.191-0.086 0.045-0.205 0.102-0.336 0.122-0.157 0.025-0.375 0.002-0.544-0.177-0.129-0.136-0.164-0.302-0.178-0.375-0.016-0.09-0.024-0.19-0.03-0.276l-0.005-0.066c-0.006-0.074-0.011-0.15-0.02-0.238-0.02-0.221-0.057-0.496-0.143-0.825-0.127-0.491-0.44-0.888-0.764-1.3L11.377 8.39c-0.16-0.206-0.363-0.478-0.436-0.77-0.042-0.163-0.049-0.353 0.024-0.547 0.072-0.19 0.203-0.336 0.352-0.448 0.428-0.32 1.128-1.013 1.743-1.652 0.303-0.314 0.576-0.607 0.775-0.822l0.005-0.006C12.738 3.422 11.418 3 10 3zm4.638 1.757L14.569 4.83c-0.201 0.218-0.48 0.516-0.788 0.836-0.602 0.626-1.352 1.373-1.855 1.753 0.03 0.066 0.1 0.176 0.242 0.359l0.124 0.157c0.316 0.398 0.774 0.973 0.959 1.684 0.103 0.395 0.147 0.725 0.171 0.984l0.001 0.01c0.588-0.33 1.21-0.296 1.66 0.053 0.459 0.354 0.653 0.971 0.472 1.572-0.081 0.268-0.273 0.495-0.434 0.664-0.135 0.141-0.296 0.289-0.446 0.425-0.037 0.035-0.074 0.068-0.11 0.1-0.188 0.174-0.35 0.332-0.474 0.485-0.127 0.157-0.178 0.268-0.191 0.342-0.04 0.227 0.072 0.497 0.29 0.772 0.101 0.128 0.209 0.234 0.291 0.31l0.025 0.021C16.03 14.074 17 12.151 17 10.001c0-2.088-0.913-3.962-2.362-5.244zm-5.84-1.402c-0.053-0.096-0.1-0.173-0.133-0.228C5.437 3.75 3 6.591 3 10c0 1.283 0.345 2.486 0.947 3.52l0.023-0.198c0.063-0.467 0.193-1.059 0.597-1.491 0.462-0.495 1.026-0.588 1.404-0.65l0.108-0.019c0.203-0.036 0.336-0.07 0.443-0.128 0.093-0.05 0.19-0.133 0.28-0.309 0.03-0.054 0.048-0.147 0.016-0.336-0.028-0.16-0.08-0.327-0.146-0.536L6.625 9.7C6.472 9.203 6.25 8.438 6.709 7.742c0.4-0.607 1.04-0.762 1.477-0.869L8.32 6.84c0.467-0.12 0.772-0.242 0.978-0.68 0.261-0.556 0.143-1.292-0.116-1.98-0.124-0.33-0.27-0.618-0.384-0.825z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M3.5 1.997l0.09 0.008c0.204 0.037 0.365 0.198 0.402 0.402L4 2.497v2.211c1.164-1.323 2.748-2.242 4.542-2.574 4.345-0.805 8.519 2.064 9.324 6.408 0.805 4.344-2.064 8.519-6.408 9.324-4.344 0.805-8.519-2.064-9.324-6.408-0.087-0.468-0.158-1.32-0.13-1.98C2.016 9.204 2.25 8.989 2.524 9c0.277 0.012 0.49 0.245 0.48 0.52-0.025 0.58 0.04 1.358 0.113 1.756 0.705 3.8 4.357 6.311 8.159 5.607 3.8-0.705 6.311-4.357 5.607-8.159-0.705-3.8-4.357-6.311-8.159-5.607C6.885 3.458 5.3 4.502 4.258 5.995l2.74 0.002 0.09 0.008c0.233 0.042 0.41 0.246 0.41 0.492 0 0.245-0.177 0.45-0.41 0.492l-0.09 0.008H3.5L3.41 6.989C3.206 6.952 3.045 6.79 3.008 6.587L3 6.497v-4l0.008-0.09C3.045 2.203 3.206 2.042 3.41 2.005L3.5 1.997zm6 4l0.09 0.008c0.204 0.037 0.365 0.198 0.402 0.402L10 6.497V10h2l0.09 0.008c0.233 0.042 0.41 0.246 0.41 0.492 0 0.245-0.177 0.45-0.41 0.491L12 11H9.5l-0.09-0.008c-0.204-0.037-0.365-0.198-0.402-0.402L9 10.5V6.498l0.008-0.09C9.045 6.203 9.206 6.042 9.41 6.005L9.5 5.997z" 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="M8.75 4c1.519 0 2.75 1.231 2.75 2.75v10.5c0 1.519-1.231 2.75-2.75 2.75h-4C3.231 20 2 18.769 2 17.25V6.75C2 5.231 3.231 4 4.75 4h4zm0 1.5h-4C4.06 5.5 3.5 6.06 3.5 6.75v10.5c0 0.69 0.56 1.25 1.25 1.25h4c0.69 0 1.25-0.56 1.25-1.25V6.75C10 6.06 9.44 5.5 8.75 5.5zM19.25 4C20.769 4 22 5.231 22 6.75v10.5c0 1.519-1.231 2.75-2.75 2.75h-4c-1.519 0-2.75-1.231-2.75-2.75V6.75C12.5 5.231 13.731 4 15.25 4h4zm0 1.5h-4C14.56 5.5 14 6.06 14 6.75v10.5c0 0.69 0.56 1.25 1.25 1.25h4c0.69 0 1.25-0.56 1.25-1.25V6.75c0-0.69-0.56-1.25-1.25-1.25zM6 9v6c0 0.414 0.336 0.75 0.75 0.75S7.5 15.414 7.5 15V9c0-0.414-0.336-0.75-0.75-0.75S6 8.586 6 9zm11.5 0.75v1.5h-1.25c-0.414 0-0.75 0.336-0.75 0.75v3c0 0.414 0.336 0.75 0.75 0.75h2c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75H17v-1.5h1.25c0.414 0 0.75-0.336 0.75-0.75V9c0-0.414-0.336-0.75-0.75-0.75h-2c-0.414 0-0.75 0.336-0.75 0.75s0.336 0.75 0.75 0.75h1.25z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M4.5 6.75c0-1.243 1.007-2.25 2.25-2.25S9 5.507 9 6.75 7.993 9 6.75 9 4.5 7.993 4.5 6.75zM6.75 3.5C4.955 3.5 3.5 4.955 3.5 6.75S4.955 10 6.75 10 10 8.545 10 6.75 8.545 3.5 6.75 3.5zm5.687 11.645c0.538 0.22 1.215 0.355 2.063 0.355 1.881 0 2.921-0.668 3.469-1.434 0.264-0.37 0.396-0.74 0.462-1.017 0.033-0.14 0.05-0.257 0.06-0.343l0.007-0.105 0.001-0.033V12.5c0-0.828-0.671-1.5-1.5-1.5h-4.628c0.24 0.29 0.42 0.629 0.525 1H17c0.276 0 0.5 0.224 0.5 0.5v0.054l-0.005 0.05c-0.005 0.049-0.015 0.122-0.037 0.213-0.043 0.182-0.13 0.425-0.303 0.667-0.327 0.459-1.037 1.016-2.656 1.016-0.731 0-1.277-0.114-1.686-0.281-0.082 0.28-0.201 0.596-0.376 0.926zM1.5 13c0-1.105 0.895-2 2-2H10c1.105 0 2 0.895 2 2v0.084c0 0.01 0 0.023-0.002 0.04-0.001 0.033-0.004 0.08-0.01 0.135-0.01 0.113-0.032 0.268-0.075 0.453-0.085 0.368-0.254 0.86-0.595 1.354C10.617 16.08 9.263 17 6.75 17c-2.513 0-3.867-0.92-4.568-1.934-0.34-0.494-0.51-0.986-0.595-1.354-0.042-0.185-0.064-0.34-0.075-0.453-0.006-0.056-0.009-0.102-0.01-0.135L1.5 13.084V13zm1 0.06v0.018l0.007 0.083c0.007 0.076 0.023 0.189 0.054 0.326 0.064 0.277 0.191 0.644 0.444 1.01C3.492 15.201 4.513 16 6.75 16s3.258-0.799 3.745-1.503c0.253-0.366 0.38-0.733 0.444-1.01 0.031-0.137 0.047-0.25 0.054-0.326C10.997 13.123 11 13.095 11 13.078V13c0-0.552-0.448-1-1-1H3.5c-0.552 0-1 0.448-1 1v0.06zM13 7.5C13 6.672 13.672 6 14.5 6S16 6.672 16 7.5 15.328 9 14.5 9 13 8.328 13 7.5zM14.5 5C13.12 5 12 6.12 12 7.5s1.12 2.5 2.5 2.5S17 8.88 17 7.5 15.88 5 14.5 5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M4.5 5.75c0-1.243 1.007-2.25 2.25-2.25S9 4.507 9 5.75 7.993 8 6.75 8 4.5 6.993 4.5 5.75zM6.75 2.5C4.955 2.5 3.5 3.955 3.5 5.75S4.955 9 6.75 9 10 7.545 10 5.75 8.545 2.5 6.75 2.5zM1.5 12c0-1.105 0.895-2 2-2H10c0.361 0 0.7 0.096 0.993 0.263-0.277 0.23-0.531 0.486-0.758 0.765C10.159 11.01 10.08 11 10 11H3.5c-0.552 0-1 0.448-1 1v0.078l0.007 0.083c0.007 0.076 0.023 0.189 0.054 0.326 0.064 0.277 0.191 0.644 0.444 1.01C3.492 14.201 4.513 15 6.75 15c0.954 0 1.687-0.145 2.252-0.367 0.008 0.35 0.049 0.69 0.12 1.02C8.476 15.87 7.695 16 6.75 16c-2.513 0-3.867-0.92-4.568-1.934-0.34-0.494-0.51-0.986-0.595-1.354-0.042-0.185-0.064-0.34-0.075-0.453-0.006-0.056-0.009-0.102-0.01-0.135L1.5 12.084V12zM13 6.5C13 5.672 13.672 5 14.5 5S16 5.672 16 6.5 15.328 8 14.5 8 13 7.328 13 6.5zM14.5 4C13.12 4 12 5.12 12 6.5S13.12 9 14.5 9 17 7.88 17 6.5 15.88 4 14.5 4zM19 14.5c0 2.485-2.015 4.5-4.5 4.5S10 16.985 10 14.5s2.015-4.5 4.5-4.5 4.5 2.015 4.5 4.5zm-2.146-1.854c-0.196-0.195-0.512-0.195-0.708 0L13.5 15.293l-0.646-0.647c-0.196-0.195-0.512-0.195-0.708 0-0.195 0.196-0.195 0.512 0 0.708l1 1c0.196 0.195 0.512 0.195 0.708 0l3-3c0.195-0.196 0.195-0.512 0-0.708z" 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="M17.5 12c3.037 0 5.5 2.463 5.5 5.5 0 3.038-2.463 5.5-5.5 5.5-3.038 0-5.5-2.462-5.5-5.5 0-3.037 2.462-5.5 5.5-5.5zm-5.478 2C11.375 15.01 11 16.21 11 17.5c0 1.644 0.61 3.146 1.617 4.29-0.802 0.142-1.675 0.211-2.617 0.211-2.89 0-5.128-0.656-6.691-2-0.829-0.712-1.306-1.75-1.306-2.844V16.25c0-1.242 1.008-2.25 2.25-2.25h7.77zm3.07 0.966l-0.068 0.058-0.058 0.07c-0.118 0.17-0.118 0.398 0 0.568l0.058 0.07 1.77 1.769-1.768 1.767-0.058 0.069c-0.118 0.17-0.118 0.398 0 0.569l0.058 0.069 0.07 0.058c0.17 0.118 0.398 0.118 0.568 0l0.07-0.058 1.766-1.767 1.77 1.77 0.069 0.057c0.17 0.118 0.398 0.118 0.568 0l0.07-0.058 0.057-0.07c0.118-0.17 0.118-0.397 0-0.568l-0.058-0.069-1.769-1.77 1.772-1.768 0.058-0.07c0.118-0.17 0.118-0.398 0-0.568l-0.058-0.07-0.07-0.057c-0.17-0.119-0.397-0.119-0.568 0l-0.069 0.057-1.772 1.77-1.77-1.77-0.069-0.057c-0.146-0.102-0.334-0.116-0.492-0.044l-0.076 0.043zM10 2.005c2.761 0 5 2.239 5 5s-2.239 5-5 5-5-2.239-5-5 2.239-5 5-5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M9.104 2.9c0.367-0.744 1.427-0.744 1.794 0l1.93 3.91 4.317 0.628c0.82 0.12 1.148 1.127 0.554 1.706l-3.124 3.044 0.738 4.3c0.14 0.816-0.717 1.44-1.451 1.054l-3.86-2.03-3.862 2.03c-0.733 0.385-1.59-0.238-1.45-1.055l0.737-4.299-3.124-3.044C1.71 8.565 2.037 7.557 2.857 7.438l4.317-0.627 1.93-3.912zm0.897 0.442l-1.93 3.911C7.925 7.548 7.643 7.753 7.318 7.8L3 8.428l3.124 3.044c0.235 0.23 0.343 0.561 0.287 0.885l-0.737 4.3 3.86-2.03c0.292-0.153 0.64-0.153 0.931 0l3.861 2.03-0.737-4.3c-0.056-0.324 0.052-0.655 0.287-0.885L17 8.428 12.684 7.8c-0.325-0.047-0.607-0.252-0.752-0.547l-1.93-3.911z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -2,150 +2,113 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorBackgroundLightest">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/reblogs"
|
||||
<org.joinmastodon.android.ui.views.AutoOrientationLinearLayout
|
||||
android:id="@+id/button_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_fluent_arrow_repeat_all_24_regular"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:importantForAccessibility="no"/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
<Button
|
||||
android:id="@+id/reblogs"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:textSize="14sp"
|
||||
android:minHeight="48dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:background="@drawable/bg_text_button"
|
||||
android:fontFamily="sans-serif"
|
||||
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_20_regular"
|
||||
android:drawablePadding="8dp"
|
||||
android:drawableTint="?android:textColorSecondary"
|
||||
tools:text="4 reblogs"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/favorites"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:textSize="14sp"
|
||||
android:minHeight="48dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:background="@drawable/bg_text_button"
|
||||
android:fontFamily="sans-serif"
|
||||
android:drawableStart="@drawable/ic_fluent_star_20_regular"
|
||||
android:drawablePadding="8dp"
|
||||
android:drawableTint="?android:textColorSecondary"
|
||||
tools:text="12 favorites"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/edit_history"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:minHeight="22dp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/post_info_reblogs"
|
||||
android:textAppearance="@style/m3_body_large" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reblogs_count"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_alignStart="@id/title"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/m3_body_medium"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:textSize="14sp"
|
||||
android:minHeight="48dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="123 456"/>
|
||||
android:background="@drawable/bg_text_button"
|
||||
android:fontFamily="sans-serif"
|
||||
android:drawableStart="@drawable/ic_fluent_history_20_regular"
|
||||
android:drawablePadding="8dp"
|
||||
android:drawableTint="?android:textColorSecondary"
|
||||
tools:text="Dec 12, 2021, 12:42 PM"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/favorites"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_fluent_star_24_regular"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:importantForAccessibility="no"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:minHeight="22dp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/post_info_favorites"
|
||||
android:textAppearance="@style/m3_body_large" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/favorites_count"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_alignStart="@id/title"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/m3_body_medium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="123 456"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/edit_history"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_fluent_edit_24_regular"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:importantForAccessibility="no"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:minHeight="22dp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/edit_history"
|
||||
android:textAppearance="@style/m3_body_large" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_edited"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_alignStart="@id/title"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/m3_body_medium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="123 456"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timestamp"
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:gravity="start|center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:minHeight="20dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="Dec 12, 2021, 12:42 PM via Mastodon for Android"/>
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:minHeight="48dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/visibility"
|
||||
android:layout_height="20dp"
|
||||
android:layout_width="20dp"
|
||||
android:src="@drawable/ic_fluent_earth_20_regular"
|
||||
android:tint="?android:textColorSecondary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timestamp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:minHeight="20dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="Dec 12, 2021, 12:42 PM via "/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/application_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="0dp"
|
||||
android:textSize="14sp"
|
||||
android:minHeight="48dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:background="@drawable/bg_text_button"
|
||||
android:fontFamily="sans-serif"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
tools:text="Mastodon for Android"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -20,7 +20,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingVertical="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -166,31 +166,66 @@
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/profile_action_btn_wrap"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_below="@id/profile_counters"
|
||||
android:padding="16dp"
|
||||
android:clipToPadding="false">
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/profile_action_btn"
|
||||
android:layout_alignParentEnd="true">
|
||||
|
||||
<FrameLayout
|
||||
android:clipToPadding="false"
|
||||
android:paddingVertical="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="4dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Edit Profile"/>
|
||||
<ProgressBar
|
||||
android:id="@+id/action_progress"
|
||||
android:layout_height="wrap_content">
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/notify_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:drawableStart="@drawable/ic_fluent_alert_24_selector" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/notify_progress"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:elevation="10dp"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateTint="?colorButtonText"
|
||||
android:outlineProvider="none"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:clipToPadding="false"
|
||||
android:paddingVertical="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:elevation="10dp"
|
||||
android:outlineProvider="none"
|
||||
android:indeterminateTint="?colorButtonText"
|
||||
android:visibility="gone"/>
|
||||
</FrameLayout>
|
||||
android:layout_height="wrap_content">
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/profile_action_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Edit Profile" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/action_progress"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:elevation="10dp"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateTint="?colorButtonText"
|
||||
android:outlineProvider="none"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
|
||||
28
mastodon/src/main/res/layout/item_list_timeline.xml
Normal file
28
mastodon/src/main/res/layout/item_list_timeline.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:src="@drawable/ic_fluent_people_community_24_regular"
|
||||
android:importantForAccessibility="no"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/m3_title_medium"
|
||||
android:fontFamily="sans-serif"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
tools:text="List"/>
|
||||
|
||||
</LinearLayout>
|
||||
8
mastodon/src/main/res/menu/hashtag_timeline.xml
Normal file
8
mastodon/src/main/res/menu/hashtag_timeline.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/follow_hashtag"
|
||||
android:icon="@drawable/ic_fluent_person_add_24_regular"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/button_follow"/>
|
||||
</menu>
|
||||
@@ -252,8 +252,12 @@
|
||||
<string name="theme_dark">Dunkel</string>
|
||||
<string name="theme_true_black">AMOLED-Modus</string>
|
||||
<string name="settings_behavior">App-Verhalten</string>
|
||||
<string name="settings_show_replies">Antworten anzeigen</string>
|
||||
<string name="settings_show_boosts">Geteilte Beiträge anzeigen</string>
|
||||
<string name="settings_load_new_posts">Automatisch neue Beiträge laden</string>
|
||||
<string name="settings_gif">Spiele animierte GIFs, Avatare und Emojis ab</string>
|
||||
<string name="settings_custom_tabs">In-App-Browser verwenden</string>
|
||||
<string name="settings_show_interaction_counts">Interaktions-Anzahlen anzeigen</string>
|
||||
<string name="settings_notifications">Benachrichtigungen</string>
|
||||
<string name="notify_me_when">Benachrichtige mich, wenn</string>
|
||||
<string name="notify_anyone">irgendjemand</string>
|
||||
@@ -301,6 +305,8 @@
|
||||
<string name="open_in_browser">Beitrag im Browser öffnen</string>
|
||||
<string name="hide_boosts_from_user">Verberge geteilte Beiträge von %s</string>
|
||||
<string name="show_boosts_from_user">Zeige geteilte Beiträge von %s</string>
|
||||
<string name="user_post_notifications_on">Benachrichtigungen über Beiträge von %s aktiviert</string>
|
||||
<string name="user_post_notifications_off">Benachrichtigungen über Beiträge von %s deaktiviert</string>
|
||||
<string name="signup_reason">Weshalb möchtest du beitreten?</string>
|
||||
<string name="signup_reason_note">Dies wird uns dabei helfen, deine Anmeldungsanfrage besser zu verarbeiten.</string>
|
||||
<string name="clear">Löschen</string>
|
||||
@@ -398,4 +404,5 @@
|
||||
<string name="install_update">Installieren</string>
|
||||
<string name="check_for_update">Auf Update prüfen</string>
|
||||
<string name="no_update_available">Kein Update verfügbar</string>
|
||||
<string name="list_timelines">Listen</string>
|
||||
</resources>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<item name="discover_users" type="id"/>
|
||||
<item name="discover_local_timeline" type="id"/>
|
||||
<item name="discover_federated_timeline" type="id"/>
|
||||
<item name="discover_lists" type="id"/>
|
||||
|
||||
<item name="notifications_all" type="id"/>
|
||||
<item name="notifications_mentions" type="id"/>
|
||||
|
||||
@@ -256,8 +256,12 @@
|
||||
<string name="theme_dark">Dark</string>
|
||||
<string name="theme_true_black">True black mode</string>
|
||||
<string name="settings_behavior">Behavior</string>
|
||||
<string name="settings_show_replies">Show replies</string>
|
||||
<string name="settings_show_boosts">Show boosts</string>
|
||||
<string name="settings_load_new_posts">Automatically load new posts</string>
|
||||
<string name="settings_gif">Play animated avatars and emoji</string>
|
||||
<string name="settings_custom_tabs">Use in-app browser</string>
|
||||
<string name="settings_show_interaction_counts">Show interaction counts</string>
|
||||
<string name="settings_notifications">Notifications</string>
|
||||
<string name="notify_me_when">Notify me when</string>
|
||||
<string name="notify_anyone">anyone</string>
|
||||
@@ -307,6 +311,8 @@
|
||||
<string name="open_in_browser">Open in browser</string>
|
||||
<string name="hide_boosts_from_user">Hide reblogs from %s</string>
|
||||
<string name="show_boosts_from_user">Show reblogs from %s</string>
|
||||
<string name="user_post_notifications_on">Turned on post notifications for %s</string>
|
||||
<string name="user_post_notifications_off">Turned off post notifications for %s</string>
|
||||
<string name="signup_reason">why do you want to join?</string>
|
||||
<string name="signup_reason_note">This will help us review your application.</string>
|
||||
<string name="clear">Clear</string>
|
||||
@@ -408,4 +414,5 @@
|
||||
<string name="privacy_policy_title">Mastodon and your privacy</string>
|
||||
<string name="privacy_policy_subtitle">Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server\'s privacy policy.</string>
|
||||
<string name="i_agree">I Agree</string>
|
||||
<string name="list_timelines">Lists</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user