Merge branch 'main' into list-timeline-views

This commit is contained in:
sk
2022-11-12 12:35:05 +01:00
19 changed files with 96 additions and 38 deletions

View File

@@ -12,6 +12,10 @@ android {
versionCode 43 versionCode 43
versionName "1.1.4" versionName "1.1.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 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",
"ja-rJP", "kab", "ko-rKR", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ru-rRU",
"sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW"
} }
buildTypes { buildTypes {

View File

@@ -16,6 +16,7 @@
android:allowBackup="true" android:allowBackup="true"
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:localeConfig="@xml/locales_config"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.Mastodon.AutoLightDark" android:theme="@style/Theme.Mastodon.AutoLightDark"

View File

@@ -12,6 +12,7 @@ import android.media.ExifInterface;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
import android.text.TextUtils;
import org.joinmastodon.android.MastodonApp; import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.ui.utils.UiUtils;
@@ -48,6 +49,8 @@ public class ResizedImageRequestBody extends CountingRequestBody{
} }
contentType=MastodonApp.context.getContentResolver().getType(uri); contentType=MastodonApp.context.getContentResolver().getType(uri);
} }
if(TextUtils.isEmpty(contentType))
contentType="image/jpeg";
if(needResize(opts.outWidth, opts.outHeight) || needCrop(opts.outWidth, opts.outHeight)){ if(needResize(opts.outWidth, opts.outHeight) || needCrop(opts.outWidth, opts.outHeight)){
Bitmap bitmap; Bitmap bitmap;
if(Build.VERSION.SDK_INT>=28){ if(Build.VERSION.SDK_INT>=28){

View File

@@ -4,7 +4,7 @@ import org.joinmastodon.android.model.Status;
public class StatusCountersUpdatedEvent{ public class StatusCountersUpdatedEvent{
public String id; public String id;
public int favorites, reblogs, replies; public long favorites, reblogs, replies;
public boolean favorited, reblogged; public boolean favorited, reblogged;
public StatusCountersUpdatedEvent(Status s){ public StatusCountersUpdatedEvent(Status s){

View File

@@ -346,6 +346,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
spoilerEdit.setVisibility(View.VISIBLE); spoilerEdit.setVisibility(View.VISIBLE);
spoilerBtn.setSelected(true); spoilerBtn.setSelected(true);
}else if(editingStatus!=null && !TextUtils.isEmpty(editingStatus.spoilerText)){ }else if(editingStatus!=null && !TextUtils.isEmpty(editingStatus.spoilerText)){
hasSpoiler=true;
spoilerEdit.setVisibility(View.VISIBLE); spoilerEdit.setVisibility(View.VISIBLE);
spoilerEdit.setText(getArguments().getString("sourceSpoiler", editingStatus.spoilerText)); spoilerEdit.setText(getArguments().getString("sourceSpoiler", editingStatus.spoilerText));
spoilerBtn.setSelected(true); spoilerBtn.setSelected(true);
@@ -365,6 +366,10 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
attachmentsView.addView(createMediaAttachmentView(att)); attachmentsView.addView(createMediaAttachmentView(att));
} }
} }
if(editingStatus!=null && editingStatus.visibility!=null) {
statusVisibility=editingStatus.visibility;
}
updateVisibilityIcon(); updateVisibilityIcon();
autocompleteViewController=new ComposeAutocompleteViewController(getActivity(), accountID); autocompleteViewController=new ComposeAutocompleteViewController(getActivity(), accountID);
@@ -389,6 +394,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
outState.putStringArrayList("pollOptions", opts); outState.putStringArrayList("pollOptions", opts);
outState.putInt("pollDuration", pollDuration); outState.putInt("pollDuration", pollDuration);
outState.putString("pollDurationStr", pollDurationStr); outState.putString("pollDurationStr", pollDurationStr);
}
outState.putBoolean("hasSpoiler", hasSpoiler); outState.putBoolean("hasSpoiler", hasSpoiler);
if(!attachments.isEmpty()){ if(!attachments.isEmpty()){
ArrayList<Parcelable> serializedAttachments=new ArrayList<>(attachments.size()); ArrayList<Parcelable> serializedAttachments=new ArrayList<>(attachments.size());
@@ -399,7 +405,6 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
} }
outState.putSerializable("visibility", statusVisibility); outState.putSerializable("visibility", statusVisibility);
} }
}
@Override @Override
public void onResume(){ public void onResume(){
@@ -523,6 +528,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
da.serverAttachment=att; da.serverAttachment=att;
da.description=att.description; da.description=att.description;
da.uri=Uri.parse(att.previewUrl); da.uri=Uri.parse(att.previewUrl);
da.state=AttachmentUploadState.DONE;
attachmentsView.addView(createMediaAttachmentView(da)); attachmentsView.addView(createMediaAttachmentView(da));
attachments.add(da); attachments.add(da);
} }
@@ -548,6 +554,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
if(editingStatus!=null){ if(editingStatus!=null){
updateCharCounter(); updateCharCounter();
visibilityBtn.setEnabled(false);
} }
} }

View File

@@ -408,7 +408,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private void bindHeaderView(){ private void bindHeaderView(){
setTitle(account.displayName); setTitle(account.displayName);
setSubtitle(getResources().getQuantityString(R.plurals.x_posts, account.statusesCount, account.statusesCount)); setSubtitle(getResources().getQuantityString(R.plurals.x_posts, (int)(account.statusesCount%1000), account.statusesCount));
ViewImageLoader.load(avatar, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(100), V.dp(100))); ViewImageLoader.load(avatar, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(100), V.dp(100)));
ViewImageLoader.load(cover, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.header : account.headerStatic, 1000, 1000)); ViewImageLoader.load(cover, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.header : account.headerStatic, 1000, 1000));
SpannableStringBuilder ssb=new SpannableStringBuilder(account.displayName); SpannableStringBuilder ssb=new SpannableStringBuilder(account.displayName);
@@ -445,9 +445,9 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
followersCount.setText(UiUtils.abbreviateNumber(account.followersCount)); followersCount.setText(UiUtils.abbreviateNumber(account.followersCount));
followingCount.setText(UiUtils.abbreviateNumber(account.followingCount)); followingCount.setText(UiUtils.abbreviateNumber(account.followingCount));
postsCount.setText(UiUtils.abbreviateNumber(account.statusesCount)); postsCount.setText(UiUtils.abbreviateNumber(account.statusesCount));
followersLabel.setText(getResources().getQuantityString(R.plurals.followers, Math.min(999, account.followersCount))); followersLabel.setText(getResources().getQuantityString(R.plurals.followers, (int)Math.min(999, account.followersCount)));
followingLabel.setText(getResources().getQuantityString(R.plurals.following, Math.min(999, account.followingCount))); followingLabel.setText(getResources().getQuantityString(R.plurals.following, (int)Math.min(999, account.followingCount)));
postsLabel.setText(getResources().getQuantityString(R.plurals.posts, Math.min(999, account.statusesCount))); postsLabel.setText(getResources().getQuantityString(R.plurals.posts, (int)Math.min(999, account.statusesCount)));
UiUtils.loadCustomEmojiInTextView(name); UiUtils.loadCustomEmojiInTextView(name);
UiUtils.loadCustomEmojiInTextView(bio); UiUtils.loadCustomEmojiInTextView(bio);

View File

@@ -12,7 +12,7 @@ public class FollowerListFragment extends AccountRelatedAccountListFragment{
@Override @Override
public void onCreate(Bundle savedInstanceState){ public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setSubtitle(getResources().getQuantityString(R.plurals.x_followers, account.followersCount, account.followersCount)); setSubtitle(getResources().getQuantityString(R.plurals.x_followers, (int)(account.followersCount%1000), account.followersCount));
} }
@Override @Override

View File

@@ -12,7 +12,7 @@ public class FollowingListFragment extends AccountRelatedAccountListFragment{
@Override @Override
public void onCreate(Bundle savedInstanceState){ public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setSubtitle(getResources().getQuantityString(R.plurals.x_following, account.followingCount, account.followingCount)); setSubtitle(getResources().getQuantityString(R.plurals.x_following, (int)(account.followingCount%1000), account.followingCount));
} }
@Override @Override

View File

@@ -11,7 +11,7 @@ public class StatusFavoritesListFragment extends StatusRelatedAccountListFragmen
@Override @Override
public void onCreate(Bundle savedInstanceState){ public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setTitle(getResources().getQuantityString(R.plurals.x_favorites, status.favouritesCount, status.favouritesCount)); setTitle(getResources().getQuantityString(R.plurals.x_favorites, (int)(status.favouritesCount%1000), status.favouritesCount));
} }
@Override @Override

View File

@@ -11,7 +11,7 @@ public class StatusReblogsListFragment extends StatusRelatedAccountListFragment{
@Override @Override
public void onCreate(Bundle savedInstanceState){ public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setTitle(getResources().getQuantityString(R.plurals.x_reblogs, status.reblogsCount, status.reblogsCount)); setTitle(getResources().getQuantityString(R.plurals.x_reblogs, (int)(status.reblogsCount%1000), status.reblogsCount));
} }
@Override @Override

View File

@@ -220,9 +220,9 @@ public class DiscoverAccountsFragment extends BaseRecyclerFragment<DiscoverAccou
followersCount.setText(UiUtils.abbreviateNumber(item.account.followersCount)); followersCount.setText(UiUtils.abbreviateNumber(item.account.followersCount));
followingCount.setText(UiUtils.abbreviateNumber(item.account.followingCount)); followingCount.setText(UiUtils.abbreviateNumber(item.account.followingCount));
postsCount.setText(UiUtils.abbreviateNumber(item.account.statusesCount)); postsCount.setText(UiUtils.abbreviateNumber(item.account.statusesCount));
followersLabel.setText(getResources().getQuantityString(R.plurals.followers, Math.min(999, item.account.followersCount))); followersLabel.setText(getResources().getQuantityString(R.plurals.followers, (int)Math.min(999, item.account.followersCount)));
followingLabel.setText(getResources().getQuantityString(R.plurals.following, Math.min(999, item.account.followingCount))); followingLabel.setText(getResources().getQuantityString(R.plurals.following, (int)Math.min(999, item.account.followingCount)));
postsLabel.setText(getResources().getQuantityString(R.plurals.posts, Math.min(999, item.account.statusesCount))); postsLabel.setText(getResources().getQuantityString(R.plurals.posts, (int)Math.min(999, item.account.statusesCount)));
relationship=relationships.get(item.account.id); relationship=relationships.get(item.account.id);
if(relationship==null){ if(relationship==null){
actionWrap.setVisibility(View.GONE); actionWrap.setVisibility(View.GONE);

View File

@@ -91,6 +91,8 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
@Override @Override
public void onItemClick(String id){ public void onItemClick(String id){
SearchResult res=getResultByID(id); SearchResult res=getResultByID(id);
if(res==null)
return;
switch(res.type){ switch(res.type){
case ACCOUNT -> { case ACCOUNT -> {
Bundle args=new Bundle(); Bundle args=new Bundle();

View File

@@ -200,7 +200,6 @@ public class SignupFragment extends AppKitFragment{
@Override @Override
public void onSuccess(Token result){ public void onSuccess(Token result){
progressDialog.dismiss(); progressDialog.dismiss();
progressDialog=null;
Account fakeAccount=new Account(); Account fakeAccount=new Account();
fakeAccount.acct=fakeAccount.username=username; fakeAccount.acct=fakeAccount.username=username;
fakeAccount.id="tmp"+System.currentTimeMillis(); fakeAccount.id="tmp"+System.currentTimeMillis();
@@ -238,7 +237,6 @@ public class SignupFragment extends AppKitFragment{
error.showToast(getActivity()); error.showToast(getActivity());
} }
progressDialog.dismiss(); progressDialog.dismiss();
progressDialog=null;
} }
}) })
.exec(instance.uri, apiToken); .exec(instance.uri, apiToken);
@@ -255,9 +253,11 @@ public class SignupFragment extends AppKitFragment{
} }
private void showProgressDialog(){ private void showProgressDialog(){
if(progressDialog==null){
progressDialog=new ProgressDialog(getActivity()); progressDialog=new ProgressDialog(getActivity());
progressDialog.setMessage(getString(R.string.loading)); progressDialog.setMessage(getString(R.string.loading));
progressDialog.setCancelable(false); progressDialog.setCancelable(false);
}
progressDialog.show(); progressDialog.show();
} }
@@ -280,7 +280,6 @@ public class SignupFragment extends AppKitFragment{
if(submitAfterGettingToken){ if(submitAfterGettingToken){
submitAfterGettingToken=false; submitAfterGettingToken=false;
progressDialog.dismiss(); progressDialog.dismiss();
progressDialog=null;
error.showToast(getActivity()); error.showToast(getActivity());
} }
} }
@@ -307,7 +306,6 @@ public class SignupFragment extends AppKitFragment{
if(submitAfterGettingToken){ if(submitAfterGettingToken){
submitAfterGettingToken=false; submitAfterGettingToken=false;
progressDialog.dismiss(); progressDialog.dismiss();
progressDialog=null;
error.showToast(getActivity()); error.showToast(getActivity());
} }
} }

View File

@@ -96,15 +96,15 @@ public class Account extends BaseModel{
/** /**
* How many statuses are attached to this account. * How many statuses are attached to this account.
*/ */
public int statusesCount; public long statusesCount;
/** /**
* The reported followers of this profile. * The reported followers of this profile.
*/ */
public int followersCount; public long followersCount;
/** /**
* The reported follows of this profile. * The reported follows of this profile.
*/ */
public int followingCount; public long followingCount;
// Optional attributes // Optional attributes

View File

@@ -34,9 +34,9 @@ public class Status extends BaseModel implements DisplayItemsParent{
public List<Hashtag> tags; public List<Hashtag> tags;
@RequiredField @RequiredField
public List<Emoji> emojis; public List<Emoji> emojis;
public int reblogsCount; public long reblogsCount;
public int favouritesCount; public long favouritesCount;
public int repliesCount; public long repliesCount;
public Instant editedAt; public Instant editedAt;
public String url; public String url;

View File

@@ -115,9 +115,9 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
followersCount.setText(UiUtils.abbreviateNumber(item.account.followersCount)); followersCount.setText(UiUtils.abbreviateNumber(item.account.followersCount));
followingCount.setText(UiUtils.abbreviateNumber(item.account.followingCount)); followingCount.setText(UiUtils.abbreviateNumber(item.account.followingCount));
postsCount.setText(UiUtils.abbreviateNumber(item.account.statusesCount)); postsCount.setText(UiUtils.abbreviateNumber(item.account.statusesCount));
followersLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.followers, Math.min(999, item.account.followersCount))); followersLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.followers, (int)Math.min(999, item.account.followersCount)));
followingLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.following, Math.min(999, item.account.followingCount))); followingLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.following, (int)Math.min(999, item.account.followingCount)));
postsLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.posts, Math.min(999, item.account.statusesCount))); postsLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.posts, (int)Math.min(999, item.account.statusesCount)));
relationship=item.parentFragment.getRelationship(item.account.id); relationship=item.parentFragment.getRelationship(item.account.id);
if(relationship==null){ if(relationship==null){
actionWrap.setVisibility(View.GONE); actionWrap.setVisibility(View.GONE);

View File

@@ -91,7 +91,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|| (item.status.visibility==StatusPrivacy.PRIVATE && item.status.account.id.equals(AccountSessionManager.getInstance().getAccount(item.accountID).self.id))); || (item.status.visibility==StatusPrivacy.PRIVATE && item.status.account.id.equals(AccountSessionManager.getInstance().getAccount(item.accountID).self.id)));
} }
private void bindButton(TextView btn, int count){ private void bindButton(TextView btn, long count){
if(count>0 && !item.hideCounts){ if(count>0 && !item.hideCounts){
btn.setText(DecimalFormat.getIntegerInstance().format(count)); btn.setText(DecimalFormat.getIntegerInstance().format(count));
btn.setCompoundDrawablePadding(V.dp(8)); btn.setCompoundDrawablePadding(V.dp(8));

View File

@@ -182,6 +182,15 @@ public class UiUtils{
} }
} }
@SuppressLint("DefaultLocale")
public static String abbreviateNumber(long n){
if(n<1_000_000_000L)
return abbreviateNumber((int)n);
double a=n/1_000_000_000.0;
return a>99f ? String.format("%,dB", (int)Math.floor(a)) : String.format("%,.1fB", n/1_000_000_000.0);
}
/** /**
* Android 6.0 has a bug where start and end compound drawables don't get tinted. * Android 6.0 has a bug where start and end compound drawables don't get tinted.
* This works around it by setting the tint colors directly to the drawables. * This works around it by setting the tint colors directly to the drawables.

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en" />
<locale android:name="ar" />
<locale android:name="bs" />
<locale android:name="ca" />
<locale android:name="cs" />
<locale android:name="de" />
<locale android:name="el" />
<locale android:name="es" />
<locale android:name="eu" />
<locale android:name="fi" />
<locale android:name="fr" />
<locale android:name="gl" />
<locale android:name="hr" />
<locale android:name="hy" />
<locale android:name="it" />
<locale android:name="iw" />
<locale android:name="ja" />
<locale android:name="kab" />
<locale android:name="ko" />
<locale android:name="oc" />
<locale android:name="pl" />
<locale android:name="pt-BR" />
<locale android:name="pt-PT" />
<locale android:name="ru" />
<locale android:name="sv" />
<locale android:name="th" />
<locale android:name="tr" />
<locale android:name="uk" />
<locale android:name="vi" />
<locale android:name="zh-Hans" />
<locale android:name="zh-Hant" />
</locale-config>