convert entity classes to Kotlin data classes (#526)

* convert entity classes to Kotlin data classes

* more data classes, code style
This commit is contained in:
Konrad Pozniak 2018-03-03 13:24:03 +01:00 committed by GitHub
parent bbbe71174a
commit 71954a277e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 604 additions and 785 deletions

View File

@ -33,6 +33,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
androidExtensions {
experimental = true
}
}
ext.supportLibraryVersion = '27.0.2'

View File

@ -72,7 +72,7 @@ public class AboutActivity extends BaseActivity {
if (response.isSuccessful()) {
List<Account> accountList = response.body();
if (!accountList.isEmpty()) {
String id = accountList.get(0).id;
String id = accountList.get(0).getId();
getPrivatePreferences().edit()
.putString("appAccountId", id)
.apply();

View File

@ -58,6 +58,7 @@ import com.keylesspalace.tusky.util.ThemeUtils;
import com.pkmmte.view.CircularImageView;
import com.squareup.picasso.Picasso;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -285,20 +286,20 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
TextView note = findViewById(R.id.account_note);
String usernameFormatted = String.format(
getString(R.string.status_username_format), account.username);
getString(R.string.status_username_format), account.getUsername());
username.setText(usernameFormatted);
displayName.setText(account.getDisplayName());
displayName.setText(account.getName());
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(account.getDisplayName());
getSupportActionBar().setTitle(account.getName());
String subtitle = String.format(getString(R.string.status_username_format),
account.username);
account.getUsername());
getSupportActionBar().setSubtitle(subtitle);
}
LinkHelper.setClickableText(note, account.note, null, new LinkListener() {
LinkHelper.setClickableText(note, account.getNote(), null, new LinkListener() {
@Override
public void onViewTag(String tag) {
Intent intent = new Intent(AccountActivity.this, ViewTagActivity.class);
@ -314,24 +315,26 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
}
});
if (account.locked) {
if (account.getLocked()) {
accountLockedView.setVisibility(View.VISIBLE);
} else {
accountLockedView.setVisibility(View.GONE);
}
Picasso.with(this)
.load(account.avatar)
.load(account.getAvatar())
.placeholder(R.drawable.avatar_default)
.into(avatar);
Picasso.with(this)
.load(account.header)
.load(account.getHeader())
.placeholder(R.drawable.account_header_default)
.into(header);
long followersCount = Long.parseLong(account.followersCount);
long followingCount = Long.parseLong(account.followingCount);
long statusesCount = Long.parseLong(account.statusesCount);
NumberFormat numberFormat = NumberFormat.getNumberInstance();
String followersCount = numberFormat.format(account.getFollowersCount());
String followingCount = numberFormat.format(account.getFollowingCount());
String statusesCount = numberFormat.format(account.getStatusesCount());
followersTextView.setText(getString(R.string.title_x_followers, followersCount));
followingTextView.setText(getString(R.string.title_x_following, followingCount));
statusesTextView.setText(getString(R.string.title_x_statuses, statusesCount));
@ -368,17 +371,17 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
}
private void onObtainRelationshipsSuccess(Relationship relation) {
if (relation.following) {
if (relation.getFollowing()) {
followState = FollowState.FOLLOWING;
} else if (relation.requested) {
} else if (relation.getRequested()) {
followState = FollowState.REQUESTED;
} else {
followState = FollowState.NOT_FOLLOWING;
}
this.blocking = relation.blocking;
this.muting = relation.muting;
this.blocking = relation.getBlocking();
this.muting = relation.getMuting();
if (relation.followedBy) {
if (relation.getFollowedBy()) {
followsYouView.setVisibility(View.VISIBLE);
} else {
followsYouView.setVisibility(View.GONE);
@ -497,9 +500,9 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
@NonNull Response<Relationship> response) {
Relationship relationship = response.body();
if (response.isSuccessful() && relationship != null) {
if (relationship.following) {
if (relationship.getFollowing()) {
followState = FollowState.FOLLOWING;
} else if (relationship.requested) {
} else if (relationship.getRequested()) {
followState = FollowState.REQUESTED;
Snackbar.make(container, R.string.state_follow_requested,
Snackbar.LENGTH_LONG).show();
@ -563,7 +566,7 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
Relationship relationship = response.body();
if (response.isSuccessful() && relationship != null) {
broadcast(TimelineReceiver.Types.BLOCK_ACCOUNT, id);
blocking = relationship.blocking;
blocking = relationship.getBlocking();
updateButtons();
} else {
onBlockFailure(id);
@ -597,7 +600,7 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
Relationship relationship = response.body();
if (response.isSuccessful() && relationship != null) {
broadcast(TimelineReceiver.Types.MUTE_ACCOUNT, id);
muting = relationship.muting;
muting = relationship.getMuting();
updateButtons();
} else {
onMuteFailure(id);
@ -630,7 +633,7 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
return false;
}
Intent intent = new ComposeActivity.IntentBuilder()
.mentionedUsernames(Collections.singleton(loadedAccount.username))
.mentionedUsernames(Collections.singleton(loadedAccount.getUsername()))
.build(this);
startActivity(intent);
return true;
@ -657,7 +660,7 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
// If the account isn't loaded yet, eat the input.
return false;
}
LinkHelper.openLink(loadedAccount.url, this);
LinkHelper.openLink(loadedAccount.getUrl(), this);
return true;
}
case R.id.action_follow: {

View File

@ -1259,7 +1259,7 @@ public final class ComposeActivity extends BaseActivity
public void onResponse(@NonNull Call<Attachment> call, @NonNull Response<Attachment> response) {
Attachment attachment = response.body();
if (response.isSuccessful() && attachment != null) {
item.description = attachment.description;
item.description = attachment.getDescription();
dialog.dismiss();
} else {
showFailedCaptionMessage();
@ -1412,17 +1412,17 @@ public final class ComposeActivity extends BaseActivity
}
private void onUploadSuccess(final QueuedMedia item, Attachment media) {
item.id = media.id;
item.id = media.getId();
item.preview.setProgress(-1);
item.readyStage = QueuedMedia.ReadyStage.UPLOADED;
/* Add the upload URL to the text field. Also, keep a reference to the span so if the user
* chooses to remove the media, the URL is also automatically removed. */
item.uploadUrl = new URLSpan(media.textUrl);
int end = 1 + media.textUrl.length();
item.uploadUrl = new URLSpan(media.getTextUrl());
int end = 1 + media.getTextUrl().length();
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(' ');
builder.append(media.textUrl);
builder.append(media.getTextUrl());
builder.setSpan(item.uploadUrl, 1, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
int cursorStart = textEditor.getSelectionStart();
int cursorEnd = textEditor.getSelectionEnd();

View File

@ -488,7 +488,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
ImageView background = headerResult.getHeaderBackgroundView();
Picasso.with(MainActivity.this)
.load(me.header)
.load(me.getHeader())
.placeholder(R.drawable.account_header_default)
.into(background);
@ -499,7 +499,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
NotificationHelper.createNotificationChannelsForAccount(am.getActiveAccount(), this);
// Show follow requests in the menu, if this is a locked account.
if (me.locked && drawer.getDrawerItem(DRAWER_ITEM_FOLLOW_REQUESTS) == null) {
if (me.getLocked() && drawer.getDrawerItem(DRAWER_ITEM_FOLLOW_REQUESTS) == null) {
PrimaryDrawerItem followRequestsItem = new PrimaryDrawerItem()
.withIdentifier(DRAWER_ITEM_FOLLOW_REQUESTS)
.withName(R.string.action_view_follow_requests)
@ -533,6 +533,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
.withNameShown(true)
.withIdentifier(acc.getId())
.withEmail(acc.getFullName()));
}
}

View File

@ -138,7 +138,7 @@ public final class NotificationPullJobCreator implements JobCreator {
for(Notification notification: notificationList){
BigInteger currentId = new BigInteger(notification.id);
BigInteger currentId = new BigInteger(notification.getId());
if(isBiggerThan(currentId, newestId)) {
newestId = currentId;

View File

@ -168,9 +168,9 @@ public class ReportActivity extends BaseActivity {
List<Status> statusList = response.body();
List<ReportAdapter.ReportStatus> itemList = new ArrayList<>();
for (Status status : statusList) {
if (status.reblog == null) {
if (status.getReblog() == null) {
ReportAdapter.ReportStatus item = new ReportAdapter.ReportStatus(
status.id, status.content, false);
status.getId(), status.getContent(), false);
itemList.add(item);
}
}

View File

@ -163,7 +163,7 @@ public class SearchActivity extends BaseActivity implements SearchView.OnQueryTe
public void onResponse(@NonNull Call<SearchResults> call, @NonNull Response<SearchResults> response) {
if (response.isSuccessful()) {
SearchResults results = response.body();
if (results.accounts != null && results.accounts.length > 0 || results.hashtags != null && results.hashtags.length > 0) {
if (results != null && (results.getAccounts().size() > 0 || results.getHashtags().size() > 0)) {
adapter.updateSearchResults(results);
hideFeedback();
} else {

View File

@ -77,7 +77,7 @@ public abstract class AccountAdapter extends RecyclerView.Adapter {
}
int end = accountList.size();
Account last = accountList.get(end - 1);
if (last != null && !findAccount(newAccounts, last.id)) {
if (last != null && !findAccount(newAccounts, last.getId())) {
accountList.addAll(newAccounts);
notifyItemRangeInserted(end, newAccounts.size());
}
@ -85,7 +85,7 @@ public abstract class AccountAdapter extends RecyclerView.Adapter {
private static boolean findAccount(List<Account> accounts, String id) {
for (Account account : accounts) {
if (account.id.equals(id)) {
if (account.getId().equals(id)) {
return true;
}
}

View File

@ -28,14 +28,14 @@ class AccountViewHolder extends RecyclerView.ViewHolder {
}
void setupWithAccount(Account account) {
accountId = account.id;
accountId = account.getId();
String format = username.getContext().getString(R.string.status_username_format);
String formattedUsername = String.format(format, account.username);
String formattedUsername = String.format(format, account.getUsername());
username.setText(formattedUsername);
displayName.setText(account.getDisplayName());
displayName.setText(account.getName());
Context context = avatar.getContext();
Picasso.with(context)
.load(account.avatar)
.load(account.getAvatar())
.placeholder(R.drawable.avatar_default)
.into(avatar);
}

View File

@ -90,13 +90,13 @@ public class BlocksAdapter extends AccountAdapter {
}
void setupWithAccount(Account account) {
id = account.id;
displayName.setText(account.getDisplayName());
id = account.getId();
displayName.setText(account.getName());
String format = username.getContext().getString(R.string.status_username_format);
String formattedUsername = String.format(format, account.username);
String formattedUsername = String.format(format, account.getUsername());
username.setText(formattedUsername);
Picasso.with(avatar.getContext())
.load(account.avatar)
.load(account.getAvatar())
.placeholder(R.drawable.avatar_default)
.into(avatar);
}

View File

@ -92,13 +92,13 @@ public class FollowRequestsAdapter extends AccountAdapter {
}
void setupWithAccount(Account account) {
id = account.id;
displayName.setText(account.getDisplayName());
id = account.getId();
displayName.setText(account.getName());
String format = username.getContext().getString(R.string.status_username_format);
String formattedUsername = String.format(format, account.username);
String formattedUsername = String.format(format, account.getUsername());
username.setText(formattedUsername);
Picasso.with(avatar.getContext())
.load(account.avatar)
.load(account.getAvatar())
.placeholder(R.drawable.avatar_default)
.into(avatar);
}

View File

@ -71,7 +71,7 @@ public class MentionAutoCompleteAdapter extends ArrayAdapter<Account>
return new Filter() {
@Override
public CharSequence convertResultToString(Object resultValue) {
return ((Account) resultValue).username;
return ((Account) resultValue).getUsername();
}
// This method is invoked in a worker thread.
@ -122,12 +122,12 @@ public class MentionAutoCompleteAdapter extends ArrayAdapter<Account>
TextView displayName = view.findViewById(R.id.display_name);
ImageView avatar = view.findViewById(R.id.avatar);
String format = getContext().getString(R.string.status_username_format);
String formattedUsername = String.format(format, account.username);
String formattedUsername = String.format(format, account.getUsername());
username.setText(formattedUsername);
displayName.setText(account.getDisplayName());
if (!account.avatar.isEmpty()) {
displayName.setText(account.getName());
if (!account.getAvatar().isEmpty()) {
Picasso.with(context)
.load(account.avatar)
.load(account.getAvatar())
.placeholder(R.drawable.avatar_default)
.transform(new RoundedTransformation(7, 0))
.into(avatar);

View File

@ -75,13 +75,13 @@ public class MutesAdapter extends AccountAdapter {
}
void setupWithAccount(Account account) {
id = account.id;
displayName.setText(account.getDisplayName());
id = account.getId();
displayName.setText(account.getName());
String format = username.getContext().getString(R.string.status_username_format);
String formattedUsername = String.format(format, account.username);
String formattedUsername = String.format(format, account.getUsername());
username.setText(formattedUsername);
Picasso.with(avatar.getContext())
.load(account.avatar)
.load(account.getAvatar())
.placeholder(R.drawable.avatar_default)
.into(avatar);
}

View File

@ -143,21 +143,20 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
holder.setCreatedAt(statusViewData.getCreatedAt());
holder.setAvatars(concreteNotificaton.getStatusViewData().getAvatar(),
concreteNotificaton.getAccount().avatar);
concreteNotificaton.getAccount().getAvatar());
}
holder.setMessage(concreteNotificaton, statusListener);
holder.setupButtons(notificationActionListener,
concreteNotificaton.getAccount().id,
concreteNotificaton.getAccount().getId(),
concreteNotificaton.getId());
break;
}
case FOLLOW: {
FollowViewHolder holder = (FollowViewHolder) viewHolder;
holder.setMessage(concreteNotificaton.getAccount().getDisplayName(),
concreteNotificaton.getAccount().username, concreteNotificaton.getAccount().avatar);
holder.setupButtons(notificationActionListener, concreteNotificaton.getAccount().id);
holder.setMessage(concreteNotificaton.getAccount().getName(),
concreteNotificaton.getAccount().getUsername(), concreteNotificaton.getAccount().getAvatar());
holder.setupButtons(notificationActionListener, concreteNotificaton.getAccount().getId());
break;
}
}
@ -380,7 +379,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
void setMessage(NotificationViewData.Concrete notificationViewData, LinkListener listener) {
this.statusViewData = notificationViewData.getStatusViewData();
String displayName = notificationViewData.getAccount().getDisplayName();
String displayName = notificationViewData.getAccount().getName();
Notification.Type type = notificationViewData.getType();
Context context = message.getContext();

View File

@ -27,7 +27,6 @@ import com.keylesspalace.tusky.entity.SearchResults;
import com.keylesspalace.tusky.interfaces.LinkListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SearchResultsAdapter extends RecyclerView.Adapter {
@ -91,12 +90,9 @@ public class SearchResultsAdapter extends RecyclerView.Adapter {
public void updateSearchResults(SearchResults results) {
if (results != null) {
if (results.accounts != null) {
accountList.addAll(Arrays.asList(results.accounts));
}
if (results.hashtags != null) {
hashtagList.addAll(Arrays.asList(results.hashtags));
}
accountList.addAll(results.getAccounts());
hashtagList.addAll(results.getHashtags());
} else {
accountList.clear();
hashtagList.clear();

View File

@ -219,12 +219,12 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
final String[] urls = new String[n];
for (int i = 0; i < n; i++) {
urls[i] = attachments[i].url;
urls[i] = attachments[i].getUrl();
}
for (int i = 0; i < n; i++) {
String previewUrl = attachments[i].previewUrl;
String description = attachments[i].description;
String previewUrl = attachments[i].getPreviewUrl();
String description = attachments[i].getDescription();
if(TextUtils.isEmpty(description)) {
previews[i].setContentDescription(context.getString(R.string.action_view_media));
@ -243,7 +243,7 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
.into(previews[i]);
}
final Attachment.Type type = attachments[i].type;
final Attachment.Type type = attachments[i].getType();
if (type == Attachment.Type.VIDEO | type == Attachment.Type.GIFV) {
overlays[i].setVisibility(View.VISIBLE);
} else {
@ -351,7 +351,7 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
// Set the label's text.
Context context = itemView.getContext();
String labelText = getLabelTypeText(context, attachments[0].type);
String labelText = getLabelTypeText(context, attachments[0].getType());
if (sensitive) {
String sensitiveText = context.getString(R.string.status_sensitive_media_title);
labelText += String.format(" (%s)", sensitiveText);
@ -359,7 +359,7 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
mediaLabel.setText(labelText);
// Set the icon next to the label.
int drawableId = getLabelIcon(attachments[0].type);
int drawableId = getLabelIcon(attachments[0].getType());
Drawable drawable = AppCompatResources.getDrawable(context, drawableId);
ThemeUtils.setDrawableTint(context, drawable, android.R.attr.textColorTertiary);
mediaLabel.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
@ -368,9 +368,9 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
int n = Math.min(attachments.length, Status.MAX_MEDIA_ATTACHMENTS);
final String[] urls = new String[n];
for (int i = 0; i < n; i++) {
urls[i] = attachments[i].url;
urls[i] = attachments[i].getUrl();
}
final Attachment.Type type = attachments[0].type;
final Attachment.Type type = attachments[0].getType();
mediaLabel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

View File

@ -24,6 +24,7 @@ import com.keylesspalace.tusky.viewdata.StatusViewData;
import com.squareup.picasso.Picasso;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Date;
class StatusDetailedViewHolder extends StatusBaseViewHolder {
@ -68,15 +69,15 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
timestampInfo.append("");
if (app.website != null) {
URLSpan span = new CustomURLSpan(app.website);
if (app.getWebsite() != null) {
URLSpan span = new CustomURLSpan(app.getWebsite());
SpannableStringBuilder text = new SpannableStringBuilder(app.name);
text.setSpan(span, 0, app.name.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
SpannableStringBuilder text = new SpannableStringBuilder(app.getName());
text.setSpan(span, 0, app.getName().length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
timestampInfo.append(text);
timestampInfo.setMovementMethod(LinkMovementMethod.getInstance());
} else {
timestampInfo.append(app.name);
timestampInfo.append(app.getName());
}
}
}
@ -85,22 +86,25 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
void setupWithStatus(final StatusViewData.Concrete status, final StatusActionListener listener,
boolean mediaPreviewEnabled) {
super.setupWithStatus(status, listener, mediaPreviewEnabled);
reblogs.setText(status.getReblogsCount());
favourites.setText(status.getFavouritesCount());
NumberFormat numberFormat = NumberFormat.getNumberInstance();
reblogs.setText(numberFormat.format(status.getReblogsCount()));
favourites.setText(numberFormat.format(status.getFavouritesCount()));
setApplication(status.getApplication());
if(status.getAttachments().length == 0 && status.getCard() != null && !TextUtils.isEmpty(status.getCard().url)) {
if(status.getAttachments().length == 0 && status.getCard() != null && !TextUtils.isEmpty(status.getCard().getUrl())) {
final Card card = status.getCard();
cardView.setVisibility(View.VISIBLE);
cardTitle.setText(card.title);
cardDescription.setText(card.description);
cardTitle.setText(card.getTitle());
cardDescription.setText(card.getDescription());
cardUrl.setText(card.url);
cardUrl.setText(card.getUrl());
if(card.width > 0 && card.height > 0 && !TextUtils.isEmpty(card.image)) {
if(card.getWidth() > 0 && card.getHeight() > 0 && !TextUtils.isEmpty(card.getImage())) {
cardImage.setVisibility(View.VISIBLE);
if(card.width > card.height) {
if(card.getWidth() > card.getHeight()) {
cardView.setOrientation(LinearLayout.VERTICAL);
cardImage.getLayoutParams().height = cardImage.getContext().getResources()
.getDimensionPixelSize(R.dimen.card_image_vertical_height);
@ -121,7 +125,7 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
}
Picasso.with(cardImage.getContext())
.load(card.image)
.load(card.getImage())
.fit()
.centerCrop()
.into(cardImage);
@ -134,7 +138,7 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
@Override
public void onClick(View v) {
LinkHelper.openLink(card.url, v.getContext());
LinkHelper.openLink(card.getUrl(), v.getContext());
}

View File

@ -109,7 +109,7 @@ class AccountManager {
activeAccount?.let{
it.accountId = account.id
it.username = account.username
it.displayName = account.getDisplayName()
it.displayName = account.name
it.profilePictureUrl = account.avatar
Log.d(TAG, "updateActiveAccount: saving account with id "+it.id)

View File

@ -13,11 +13,10 @@
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
package com.keylesspalace.tusky.entity
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.SerializedName
public class AccessToken {
@SerializedName("access_token")
public String accessToken;
}
data class AccessToken(
@SerializedName("access_token") val accessToken: String
)

View File

@ -1,130 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Spanned;
import com.google.gson.annotations.SerializedName;
import com.keylesspalace.tusky.util.HtmlUtils;
public class Account implements Parcelable {
public String id;
@SerializedName("username")
public String localUsername;
@SerializedName("acct")
public String username;
@SerializedName("display_name")
public String displayName;
public Spanned note;
public String url;
public String avatar;
public String header;
public boolean locked;
@SerializedName("followers_count")
public String followersCount;
@SerializedName("following_count")
public String followingCount;
@SerializedName("statuses_count")
public String statusesCount;
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object other) {
if (this.id == null) {
return this == other;
} else if (!(other instanceof Account)) {
return false;
}
Account account = (Account) other;
return account.id.equals(this.id);
}
public String getDisplayName() {
if (displayName.length() == 0) {
return localUsername;
}
return displayName;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(localUsername);
dest.writeString(username);
dest.writeString(displayName);
dest.writeString(HtmlUtils.toHtml(note));
dest.writeString(url);
dest.writeString(avatar);
dest.writeString(header);
dest.writeBooleanArray(new boolean[] { locked });
dest.writeString(followersCount);
dest.writeString(followingCount);
dest.writeString(statusesCount);
}
public Account() {}
protected Account(Parcel in) {
id = in.readString();
localUsername = in.readString();
username = in.readString();
displayName = in.readString();
note = HtmlUtils.fromHtml(in.readString());
url = in.readString();
avatar = in.readString();
header = in.readString();
boolean[] lockedArray = new boolean[1];
in.readBooleanArray(lockedArray);
locked = lockedArray[0];
followersCount = in.readString();
followingCount = in.readString();
statusesCount = in.readString();
}
public static final Creator<Account> CREATOR = new Creator<Account>() {
@Override
public Account createFromParcel(Parcel source) {
return new Account(source);
}
@Override
public Account[] newArray(int size) {
return new Account[size];
}
};
}

View File

@ -0,0 +1,69 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity
import android.os.Parcel
import android.os.Parcelable
import android.text.Spanned
import com.google.gson.annotations.SerializedName
import com.keylesspalace.tusky.util.HtmlUtils
import kotlinx.android.parcel.Parceler
import kotlinx.android.parcel.Parcelize
import kotlinx.android.parcel.WriteWith
@Parcelize
data class Account(
val id: String,
@SerializedName("username") val localUsername: String,
@SerializedName("acct") val username: String,
@SerializedName("display_name") val displayName: String,
val note: @WriteWith<SpannedParceler>() Spanned,
val url: String,
val avatar: String,
val header: String,
val locked: Boolean = false,
@SerializedName("followers_count") val followersCount: Int,
@SerializedName("following_count") val followingCount: Int,
@SerializedName("statuses_count") val statusesCount: Int
) : Parcelable {
val name: String
get() = if (displayName.isEmpty()) {
localUsername
} else displayName
override fun hashCode(): Int {
return id.hashCode()
}
override fun equals(other: Any?): Boolean {
if (other !is Account) {
return false
}
val account = other as Account?
return account?.id == this.id
}
object SpannedParceler : Parceler<Spanned> {
override fun create(parcel: Parcel) = HtmlUtils.fromHtml(parcel.readString())
override fun Spanned.write(parcel: Parcel, flags: Int) {
parcel.writeString(HtmlUtils.toHtml(this))
}
}
}

View File

@ -13,14 +13,11 @@
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
package com.keylesspalace.tusky.entity
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.SerializedName
public class AppCredentials {
@SerializedName("client_id")
public String clientId;
@SerializedName("client_secret")
public String clientSecret;
}
data class AppCredentials(
@SerializedName("client_id") val clientId: String,
@SerializedName("client_secret") val clientSecret: String
)

View File

@ -1,79 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
public class Attachment {
public String id;
public String url;
@SerializedName("preview_url")
public String previewUrl;
@SerializedName("text_url")
public String textUrl;
public Type type;
public String description;
public static class Meta {
public MediaProperties original;
public MediaProperties small;
}
public static class MediaProperties {
public int width;
public int height;
public float aspect;
}
@JsonAdapter(MediaTypeDeserializer.class)
public enum Type {
@SerializedName("image")
IMAGE,
@SerializedName("gifv")
GIFV,
@SerializedName("video")
VIDEO,
@SerializedName("unknown")
UNKNOWN
}
static class MediaTypeDeserializer implements JsonDeserializer<Type> {
@Override
public Type deserialize(JsonElement json, java.lang.reflect.Type classOfT, JsonDeserializationContext context)
throws JsonParseException {
switch(json.toString()) {
case "\"image\"":
return Type.IMAGE;
case "\"gifv\"":
return Type.GIFV;
case "\"video\"":
return Type.VIDEO;
default:
return Type.UNKNOWN;
}
}
}
}

View File

@ -0,0 +1,57 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import com.google.gson.annotations.JsonAdapter
import com.google.gson.annotations.SerializedName
data class Attachment(
var id: String,
var url: String,
@SerializedName("preview_url") val previewUrl: String,
@SerializedName("text_url") val textUrl: String?,
var type: Type,
var description: String?
) {
@JsonAdapter(MediaTypeDeserializer::class)
enum class Type {
@SerializedName("image")
IMAGE,
@SerializedName("gifv")
GIFV,
@SerializedName("video")
VIDEO,
@SerializedName("unknown")
UNKNOWN
}
class MediaTypeDeserializer : JsonDeserializer<Type> {
@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, classOfT: java.lang.reflect.Type, context: JsonDeserializationContext): Type {
return when (json.toString()) {
"\"image\"" -> Type.IMAGE
"\"gifv\"" -> Type.GIFV
"\"video\"" -> Type.VIDEO
else -> Type.UNKNOWN
}
}
}
}

View File

@ -1,92 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
import android.os.Parcel;
import android.os.Parcelable;
public class Card implements Parcelable {
public String url;
public String title;
public String description;
public String image;
public String type;
public int width;
public int height;
@Override
public int hashCode() {
return url.hashCode();
}
@Override
public boolean equals(Object other) {
if (this.url == null) {
return this == other;
} else if (!(other instanceof Card)) {
return false;
}
Card account = (Card) other;
return account.url.equals(this.url);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(url);
dest.writeString(title);
dest.writeString(description);
dest.writeString(image);
dest.writeString(type);
dest.writeInt(width);
dest.writeInt(height);
}
public Card() {}
private Card(Parcel in) {
url = in.readString();
title = in.readString();
description = in.readString();
image = in.readString();
type = in.readString();
width = in.readInt();
height = in.readInt();
}
public static final Creator<Card> CREATOR = new Creator<Card>() {
@Override
public Card createFromParcel(Parcel source) {
return new Card(source);
}
@Override
public Card[] newArray(int size) {
return new Card[size];
}
};
}

View File

@ -13,21 +13,32 @@
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
package com.keylesspalace.tusky.entity
import com.google.gson.annotations.SerializedName;
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
public class Relationship {
public String id;
@Parcelize
data class Card(
val url: String,
val title: String,
val description: String,
val image: String,
val type: String,
val width: Int,
val height: Int
) : Parcelable {
override fun hashCode(): Int {
return url.hashCode()
}
override fun equals(other: Any?): Boolean {
if (other !is Card) {
return false
}
val account = other as Card?
return account?.url == this.url
}
public boolean following;
@SerializedName("followed_by")
public boolean followedBy;
public boolean blocking;
public boolean muting;
public boolean requested;
}

View File

@ -13,12 +13,17 @@
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
package com.keylesspalace.tusky.entity
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.SerializedName
public class Notification {
public enum Type {
data class Notification(
val type: Type,
val id: String,
val account: Account,
val status: Status?) {
enum class Type {
@SerializedName("mention")
MENTION,
@SerializedName("reblog")
@ -26,30 +31,18 @@ public class Notification {
@SerializedName("favourite")
FAVOURITE,
@SerializedName("follow")
FOLLOW,
FOLLOW
}
public Type type;
public String id;
public Account account;
public Status status;
@Override
public int hashCode() {
return id.hashCode();
override fun hashCode(): Int {
return id.hashCode()
}
@Override
public boolean equals(Object other) {
if (this.id == null) {
return this == other;
} else if (!(other instanceof Notification)) {
return false;
override fun equals(other: Any?): Boolean {
if (other !is Notification) {
return false
}
Notification notification = (Notification) other;
return notification.id.equals(this.id);
val notification = other as Notification?
return notification?.id == this.id
}
}

View File

@ -0,0 +1,11 @@
package com.keylesspalace.tusky.entity
import com.google.gson.annotations.SerializedName
data class Profile(
@SerializedName("display_name") val displayName: String?,
val note: String?,
val avatar: String?,
val header: String? = null
)

View File

@ -0,0 +1,27 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity
import com.google.gson.annotations.SerializedName
data class Relationship (
val id: String,
val following: Boolean,
@SerializedName("followed_by") val followedBy: Boolean,
val blocking: Boolean,
val muting: Boolean,
val requested: Boolean
)

View File

@ -13,11 +13,10 @@
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
package com.keylesspalace.tusky.entity
import java.util.List;
public class StatusContext {
public List<Status> ancestors;
public List<Status> descendants;
}
data class SearchResults (
val accounts: List<Account>,
val statuses: List<Status>,
val hashtags: List<String>
)

View File

@ -1,189 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
import android.text.Spanned;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
import java.util.List;
public class Status {
public String url;
@SerializedName("reblogs_count")
public String reblogsCount;
@SerializedName("favourites_count")
public String favouritesCount;
@SerializedName("in_reply_to_id")
public String inReplyToId;
@SerializedName("in_reply_to_account_id")
public String inReplyToAccountId;
public String getActionableId() {
return reblog == null ? id : reblog.id;
}
public Status getActionableStatus() {
return reblog == null ? this : reblog;
}
public enum Visibility {
UNKNOWN(0),
@SerializedName("public")
PUBLIC(1),
@SerializedName("unlisted")
UNLISTED(2),
@SerializedName("private")
PRIVATE(3),
@SerializedName("direct")
DIRECT(4);
private final int num;
Visibility(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public static Visibility byNum(int num) {
switch (num) {
case 4: return DIRECT;
case 3: return PRIVATE;
case 2: return UNLISTED;
case 1: return PUBLIC;
case 0: default: return UNKNOWN;
}
}
public static Visibility byString(String s) {
switch (s) {
case "public": return PUBLIC;
case "unlisted": return UNLISTED;
case "private": return PRIVATE;
case "direct": return DIRECT;
case "unknown": default: return UNKNOWN;
}
}
public String serverString() {
switch (this) {
case PUBLIC: return "public";
case UNLISTED: return "unlisted";
case PRIVATE: return "private";
case DIRECT: return "direct";
case UNKNOWN: default: return "unknown";
}
}
}
public String id;
public Account account;
public Spanned content;
public Status reblog;
@SerializedName("created_at")
public Date createdAt;
public boolean reblogged;
public boolean favourited;
public boolean sensitive;
public List<Emoji> emojis;
@SerializedName("spoiler_text")
public String spoilerText;
public Visibility visibility;
public Visibility getVisibility() {
return visibility == null ? Visibility.UNLISTED : visibility;
}
public boolean rebloggingAllowed() {
return visibility != null
&& visibility != Visibility.PRIVATE
&& visibility != Visibility.DIRECT
&& visibility != Visibility.UNKNOWN;
}
@SerializedName("media_attachments")
public Attachment[] attachments;
public Mention[] mentions;
public Application application;
public static final int MAX_MEDIA_ATTACHMENTS = 4;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Status status = (Status) o;
return id != null ? id.equals(status.id) : status.id == null;
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
public static final class Mention {
public String id;
public String url;
@SerializedName("acct")
public String username;
@SerializedName("username")
public String localUsername;
}
public static class Application {
public String name;
public String website;
}
@SuppressWarnings("unused")
public static class Emoji {
private String shortcode;
private String url;
public String getShortcode() {
return shortcode;
}
public String getUrl() {
return url;
}
}
}

View File

@ -0,0 +1,142 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity
import android.text.Spanned
import com.google.gson.annotations.SerializedName
import java.util.*
data class Status(
var id: String,
var url: String,
val account: Account,
@SerializedName("in_reply_to_id") var inReplyToId: String?,
@SerializedName("in_reply_to_account_id") val inReplyToAccountId: String?,
val reblog: Status?,
val content: Spanned,
@SerializedName("created_at") val createdAt: Date,
val emojis: List<Emoji>,
@SerializedName("reblogs_count") val reblogsCount: Int,
@SerializedName("favourites_count") val favouritesCount: Int,
var reblogged: Boolean?,
var favourited: Boolean?,
var sensitive: Boolean,
@SerializedName("spoiler_text") val spoilerText: String,
val visibility: Visibility,
@SerializedName("media_attachments") var attachments: Array<Attachment>,
val mentions: Array<Mention>,
val application: Application?
) {
val actionableId: String?
get() = reblog?.id ?: id
val actionableStatus: Status
get() = reblog ?: this
enum class Visibility(val num: Int) {
UNKNOWN(0),
@SerializedName("public")
PUBLIC(1),
@SerializedName("unlisted")
UNLISTED(2),
@SerializedName("private")
PRIVATE(3),
@SerializedName("direct")
DIRECT(4);
fun serverString(): String {
return when (this) {
PUBLIC -> "public"
UNLISTED -> "unlisted"
PRIVATE -> "private"
DIRECT -> "direct"
UNKNOWN -> "unknown"
}
}
companion object {
@JvmStatic
fun byNum(num: Int): Visibility {
return when (num) {
4 -> DIRECT
3 -> PRIVATE
2 -> UNLISTED
1 -> PUBLIC
0 -> UNKNOWN
else -> UNKNOWN
}
}
@JvmStatic
fun byString(s: String): Visibility {
return when (s) {
"public" -> PUBLIC
"unlisted" -> UNLISTED
"private" -> PRIVATE
"direct" -> DIRECT
"unknown" -> UNKNOWN
else -> UNKNOWN
}
}
}
}
fun rebloggingAllowed(): Boolean {
return (visibility != Visibility.PRIVATE && visibility != Visibility.DIRECT && visibility != Visibility.UNKNOWN)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val status = other as Status?
return id == status?.id
}
override fun hashCode(): Int {
return id.hashCode()
}
class Mention {
var id: String? = null
var url: String? = null
@SerializedName("acct")
var username: String? = null
@SerializedName("username")
var localUsername: String? = null
}
class Application {
var name: String? = null
var website: String? = null
}
class Emoji {
val shortcode: String? = null
val url: String? = null
}
companion object {
const val MAX_MEDIA_ATTACHMENTS = 4
}
}

View File

@ -13,10 +13,9 @@
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.entity;
package com.keylesspalace.tusky.entity
public class SearchResults {
public Account[] accounts;
public Status[] statuses;
public String[] hashtags;
}
data class StatusContext (
val ancestors: List<Status>,
val descendants: List<Status>
)

View File

@ -25,7 +25,6 @@ import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -213,7 +212,7 @@ class AccountMediaFragment : BaseFragment() {
intent.putExtra("url", urls[currentIndex])
startActivity(intent)
}
Attachment.Type.UNKNOWN, null -> {
Attachment.Type.UNKNOWN -> {
}/* Intentionally do nothing. This case is here is to handle when new attachment
* types are added to the API before code is added here to handle them. So, the
* best fallback is to just show the preview and ignore requests to view them. */

View File

@ -262,21 +262,21 @@ public class NotificationsFragment extends SFragment implements
@Override
public void onReply(int position) {
super.reply(notifications.get(position).getAsRight().status);
super.reply(notifications.get(position).getAsRight().getStatus());
}
@Override
public void onReblog(final boolean reblog, final int position) {
final Notification notification = notifications.get(position).getAsRight();
final Status status = notification.status;
final Status status = notification.getStatus();
reblogWithCallback(status, reblog, new Callback<Status>() {
@Override
public void onResponse(@NonNull Call<Status> call, @NonNull retrofit2.Response<Status> response) {
if (response.isSuccessful()) {
status.reblogged = reblog;
status.setReblogged(reblog);
if (status.reblog != null) {
status.reblog.reblogged = reblog;
if (status.getReblog() != null) {
status.getReblog().setReblogged(reblog);
}
NotificationViewData.Concrete viewdata = (NotificationViewData.Concrete)notifications.getPairedItem(position);
@ -296,7 +296,7 @@ public class NotificationsFragment extends SFragment implements
@Override
public void onFailure(@NonNull Call<Status> call, @NonNull Throwable t) {
Log.d(getClass().getSimpleName(), "Failed to reblog status: " + status.id, t);
Log.d(getClass().getSimpleName(), "Failed to reblog status: " + status.getId(), t);
}
});
}
@ -305,15 +305,15 @@ public class NotificationsFragment extends SFragment implements
@Override
public void onFavourite(final boolean favourite, final int position) {
final Notification notification = notifications.get(position).getAsRight();
final Status status = notification.status;
final Status status = notification.getStatus();
favouriteWithCallback(status, favourite, new Callback<Status>() {
@Override
public void onResponse(@NonNull Call<Status> call, @NonNull retrofit2.Response<Status> response) {
if (response.isSuccessful()) {
status.favourited = favourite;
status.setFavourited(favourite);
if (status.reblog != null) {
status.reblog.favourited = favourite;
if (status.getReblog() != null) {
status.getReblog().setFavourited(favourite);
}
NotificationViewData.Concrete viewdata = (NotificationViewData.Concrete)notifications.getPairedItem(position);
@ -334,7 +334,7 @@ public class NotificationsFragment extends SFragment implements
@Override
public void onFailure(@NonNull Call<Status> call, @NonNull Throwable t) {
Log.d(getClass().getSimpleName(), "Failed to favourite status: " + status.id, t);
Log.d(getClass().getSimpleName(), "Failed to favourite status: " + status.getId(), t);
}
});
}
@ -342,7 +342,7 @@ public class NotificationsFragment extends SFragment implements
@Override
public void onMore(View view, int position) {
Notification notification = notifications.get(position).getAsRight();
super.more(notification.status, view, position);
super.more(notification.getStatus(), view, position);
}
@Override
@ -354,13 +354,13 @@ public class NotificationsFragment extends SFragment implements
@Override
public void onViewThread(int position) {
Notification notification = notifications.get(position).getAsRight();
super.viewThread(notification.status);
super.viewThread(notification.getStatus());
}
@Override
public void onOpenReblog(int position) {
Notification notification = notifications.get(position).getAsRight();
onViewAccount(notification.account.id);
onViewAccount(notification.getAccount().getId());
}
@Override
@ -401,7 +401,7 @@ public class NotificationsFragment extends SFragment implements
Log.e(TAG, "Failed to load more, invalid placeholder position: " + position);
return;
}
sendFetchNotificationsRequest(previous.id, next.id, FetchEnd.MIDDLE, position);
sendFetchNotificationsRequest(previous.getId(), next.getId(), FetchEnd.MIDDLE, position);
NotificationViewData notificationViewData =
new NotificationViewData.Placeholder(true);
notifications.setPairedItem(position, notificationViewData);
@ -425,8 +425,8 @@ public class NotificationsFragment extends SFragment implements
public void onViewStatusForNotificationId(String notificationId) {
for (Either<Placeholder, Notification> either : notifications) {
Notification notification = either.getAsRightOrNull();
if (notification != null && notification.id.equals(notificationId)) {
super.viewThread(notification.status);
if (notification != null && notification.getId().equals(notificationId)) {
super.viewThread(notification.getStatus());
return;
}
}
@ -462,7 +462,7 @@ public class NotificationsFragment extends SFragment implements
while (iterator.hasNext()) {
Either<Placeholder, Notification> notification = iterator.next();
Notification maybeNotification = notification.getAsRightOrNull();
if (maybeNotification != null && maybeNotification.account.id.equals(accountId)) {
if (maybeNotification != null && maybeNotification.getAccount().getId().equals(accountId)) {
iterator.remove();
}
}
@ -590,7 +590,7 @@ public class NotificationsFragment extends SFragment implements
BigInteger lastNoti = new BigInteger(account.getLastNotificationId());
for (Notification noti: notifications) {
BigInteger a = new BigInteger(noti.id);
BigInteger a = new BigInteger(noti.getId());
if(isBiggerThan(a, lastNoti)) {
lastNoti = a;
}

View File

@ -98,12 +98,12 @@ public abstract class SFragment extends BaseFragment implements AdapterItemRemov
String inReplyToId = status.getActionableId();
Status actionableStatus = status.getActionableStatus();
Status.Visibility replyVisibility = actionableStatus.getVisibility();
String contentWarning = actionableStatus.spoilerText;
Status.Mention[] mentions = actionableStatus.mentions;
String contentWarning = actionableStatus.getSpoilerText();
Status.Mention[] mentions = actionableStatus.getMentions();
List<String> mentionedUsernames = new ArrayList<>();
mentionedUsernames.add(actionableStatus.account.username);
mentionedUsernames.add(actionableStatus.getAccount().getUsername());
for (Status.Mention mention : mentions) {
mentionedUsernames.add(mention.username);
mentionedUsernames.add(mention.getUsername());
}
mentionedUsernames.remove(loggedInUsername);
Intent intent = new ComposeActivity.IntentBuilder()
@ -111,8 +111,8 @@ public abstract class SFragment extends BaseFragment implements AdapterItemRemov
.replyVisibility(replyVisibility)
.contentWarning(contentWarning)
.mentionedUsernames(mentionedUsernames)
.repyingStatusAuthor(actionableStatus.account.localUsername)
.replyingStatusContent(actionableStatus.content.toString())
.repyingStatusAuthor(actionableStatus.getAccount().getLocalUsername())
.replyingStatusContent(actionableStatus.getContent().toString())
.build(getContext());
startActivityForResult(intent, COMPOSE_RESULT);
}
@ -146,7 +146,7 @@ public abstract class SFragment extends BaseFragment implements AdapterItemRemov
protected void openReblog(@Nullable final Status status) {
if (status == null) return;
viewAccount(status.account.id);
viewAccount(status.getAccount().getId());
}
private void mute(String id) {
@ -195,10 +195,10 @@ public abstract class SFragment extends BaseFragment implements AdapterItemRemov
protected void more(final Status status, View view, final int position) {
final String id = status.getActionableId();
final String accountId = status.getActionableStatus().account.id;
final String accountUsename = status.getActionableStatus().account.username;
final Spanned content = status.getActionableStatus().content;
final String statusUrl = status.getActionableStatus().url;
final String accountId = status.getActionableStatus().getAccount().getId();
final String accountUsename = status.getActionableStatus().getAccount().getUsername();
final Spanned content = status.getActionableStatus().getContent();
final String statusUrl = status.getActionableStatus().getUrl();
PopupMenu popup = new PopupMenu(getContext(), view);
// Give a different menu depending on whether this is the user's own toot or not.
if (loggedInAccountId == null || !loggedInAccountId.equals(accountId)) {
@ -213,9 +213,9 @@ public abstract class SFragment extends BaseFragment implements AdapterItemRemov
switch (item.getItemId()) {
case R.id.status_share_content: {
StringBuilder sb = new StringBuilder();
sb.append(status.account.username);
sb.append(status.getAccount().getUsername());
sb.append(" - ");
sb.append(status.content.toString());
sb.append(status.getContent().toString());
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
@ -301,7 +301,7 @@ public abstract class SFragment extends BaseFragment implements AdapterItemRemov
protected void viewThread(Status status) {
Intent intent = new Intent(getContext(), ViewThreadActivity.class);
intent.putExtra("id", status.getActionableId());
intent.putExtra("url", status.getActionableStatus().url);
intent.putExtra("url", status.getActionableStatus().getUrl());
startActivity(intent);
}

View File

@ -310,10 +310,10 @@ public class TimelineFragment extends SFragment implements
public void onResponse(@NonNull Call<Status> call, @NonNull Response<Status> response) {
if (response.isSuccessful()) {
status.reblogged = reblog;
status.setReblogged(reblog);
if (status.reblog != null) {
status.reblog.reblogged = reblog;
if (status.getReblog() != null) {
status.getReblog().setReblogged(reblog);
}
Pair<StatusViewData.Concrete, Integer> actual =
@ -331,7 +331,7 @@ public class TimelineFragment extends SFragment implements
@Override
public void onFailure(@NonNull Call<Status> call, @NonNull Throwable t) {
Log.d(TAG, "Failed to reblog status " + status.id, t);
Log.d(TAG, "Failed to reblog status " + status.getId(), t);
}
});
}
@ -345,10 +345,10 @@ public class TimelineFragment extends SFragment implements
public void onResponse(@NonNull Call<Status> call, @NonNull Response<Status> response) {
if (response.isSuccessful()) {
status.favourited = favourite;
status.setFavourited(favourite);
if (status.reblog != null) {
status.reblog.favourited = favourite;
if (status.getReblog() != null) {
status.getReblog().setFavourited(favourite);
}
Pair<StatusViewData.Concrete, Integer> actual =
@ -366,7 +366,7 @@ public class TimelineFragment extends SFragment implements
@Override
public void onFailure(@NonNull Call<Status> call, @NonNull Throwable t) {
Log.d(TAG, "Failed to favourite status " + status.id, t);
Log.d(TAG, "Failed to favourite status " + status.getId(), t);
}
});
}
@ -409,7 +409,7 @@ public class TimelineFragment extends SFragment implements
Log.e(TAG, "Failed to load more at " + position + ", wrong placeholder position");
return;
}
sendFetchTimelineRequest(fromStatus.id, toStatus.id, FetchEnd.MIDDLE, position);
sendFetchTimelineRequest(fromStatus.getId(), toStatus.getId(), FetchEnd.MIDDLE, position);
StatusViewData newViewData = new StatusViewData.Placeholder(true);
statuses.setPairedItem(position, newViewData);
@ -499,7 +499,7 @@ public class TimelineFragment extends SFragment implements
Iterator<Either<Placeholder, Status>> iterator = statuses.iterator();
while (iterator.hasNext()) {
Status status = iterator.next().getAsRightOrNull();
if (status != null && status.account.id.equals(accountId)) {
if (status != null && status.getAccount().getId().equals(accountId)) {
iterator.remove();
}
}
@ -682,8 +682,8 @@ public class TimelineFragment extends SFragment implements
Iterator<Status> it = statuses.iterator();
while (it.hasNext()) {
Status status = it.next();
if ((status.inReplyToId != null && filterRemoveReplies)
|| (status.reblog != null && filterRemoveReblogs)) {
if ((status.getInReplyToId() != null && filterRemoveReplies)
|| (status.getReblog() != null && filterRemoveReblogs)) {
it.remove();
}
}
@ -733,7 +733,7 @@ public class TimelineFragment extends SFragment implements
Status last = statuses.get(end - 1).getAsRightOrNull();
// I was about to replace findStatus with indexOf but it is incorrect to compare value
// types by ID anyway and we should change equals() for Status, I think, so this makes sense
if (last != null && !findStatus(newStatuses, last.id)) {
if (last != null && !findStatus(newStatuses, last.getId())) {
statuses.addAll(listStatusList(newStatuses));
List<StatusViewData> newViewDatas = statuses.getPairedCopy()
.subList(statuses.size() - newStatuses.size(), statuses.size());
@ -775,7 +775,7 @@ public class TimelineFragment extends SFragment implements
private static boolean findStatus(List<Status> statuses, String id) {
for (Status status : statuses) {
if (status.id.equals(id)) {
if (status.getId().equals(id)) {
return true;
}
}
@ -794,7 +794,7 @@ public class TimelineFragment extends SFragment implements
// Unlikely, but data could change between the request and response
if ((someOldViewData instanceof StatusViewData.Placeholder) ||
!((StatusViewData.Concrete) someOldViewData).getId().equals(status.id)) {
!((StatusViewData.Concrete) someOldViewData).getId().equals(status.getId())) {
// try to find the status we need to update
int foundPos = statuses.indexOf(Either.<Placeholder, Status>right(status));
if (foundPos < 0) return null; // okay, it's hopeless, give up

View File

@ -163,10 +163,10 @@ public class ViewThreadFragment extends SFragment implements
@Override
public void onResponse(@NonNull Call<Status> call, @NonNull Response<Status> response) {
if (response.isSuccessful()) {
status.reblogged = reblog;
status.setReblogged(reblog);
if (status.reblog != null) {
status.reblog.reblogged = reblog;
if (status.getReblog() != null) {
status.getReblog().setReblogged(reblog);
}
StatusViewData.Concrete viewdata = statuses.getPairedItem(position);
@ -183,7 +183,7 @@ public class ViewThreadFragment extends SFragment implements
@Override
public void onFailure(@NonNull Call<Status> call, @NonNull Throwable t) {
Log.d(getClass().getSimpleName(), "Failed to reblog status: " + status.id);
Log.d(getClass().getSimpleName(), "Failed to reblog status: " + status.getId());
t.printStackTrace();
}
});
@ -196,10 +196,10 @@ public class ViewThreadFragment extends SFragment implements
@Override
public void onResponse(@NonNull Call<Status> call, @NonNull Response<Status> response) {
if (response.isSuccessful()) {
status.favourited = favourite;
status.setFavourited(favourite);
if (status.reblog != null) {
status.reblog.favourited = favourite;
if (status.getReblog() != null) {
status.getReblog().setFavourited(favourite);
}
StatusViewData.Concrete viewdata = statuses.getPairedItem(position);
@ -216,7 +216,7 @@ public class ViewThreadFragment extends SFragment implements
@Override
public void onFailure(@NonNull Call<Status> call, @NonNull Throwable t) {
Log.d(getClass().getSimpleName(), "Failed to favourite status: " + status.id);
Log.d(getClass().getSimpleName(), "Failed to favourite status: " + status.getId());
t.printStackTrace();
}
});
@ -236,7 +236,7 @@ public class ViewThreadFragment extends SFragment implements
@Override
public void onViewThread(int position) {
Status status = statuses.get(position);
if (thisThreadsStatusId.equals(status.id)) {
if (thisThreadsStatusId.equals(status.getId())) {
// If already viewing this thread, don't reopen it.
return;
}
@ -304,7 +304,7 @@ public class ViewThreadFragment extends SFragment implements
Iterator<Status> iterator = statuses.iterator();
while (iterator.hasNext()) {
Status s = iterator.next();
if (s.account.id.equals(accountId)) {
if (s.getAccount().getId().equals(accountId)) {
iterator.remove();
}
}
@ -347,7 +347,7 @@ public class ViewThreadFragment extends SFragment implements
StatusContext context = response.body();
if (response.isSuccessful() && context != null) {
swipeRefreshLayout.setRefreshing(false);
setContext(context.ancestors, context.descendants);
setContext(context.getAncestors(), context.getDescendants());
} else {
onThreadRequestFailure(id);
}

View File

@ -95,9 +95,9 @@ public class LinkHelper {
* that can't be found then just go with whichever one matched last. */
String id = null;
for (Status.Mention mention : mentions) {
if (mention.localUsername.equalsIgnoreCase(accountUsername)) {
id = mention.id;
if (mention.url.contains(getDomain(span.getURL()))) {
if (mention.getLocalUsername().equalsIgnoreCase(accountUsername)) {
id = mention.getId();
if (mention.getUrl().contains(getDomain(span.getURL()))) {
break;
}
}

View File

@ -89,7 +89,7 @@ public class NotificationHelper {
for (int i = 0; i < currentNotifications.length(); i++) {
try {
if (currentNotifications.getString(i).equals(body.account.getDisplayName())) {
if (currentNotifications.getString(i).equals(body.getAccount().getName())) {
alreadyContains = true;
}
} catch (JSONException e) {
@ -98,7 +98,7 @@ public class NotificationHelper {
}
if (!alreadyContains) {
currentNotifications.put(body.account.getDisplayName());
currentNotifications.put(body.getAccount().getName());
}
account.setActiveNotifications(currentNotifications.toString());
@ -131,7 +131,7 @@ public class NotificationHelper {
builder.setContentTitle(titleForType(context, body))
.setContentText(bodyForType(body));
if(body.type == Notification.Type.MENTION) {
if(body.getType() == Notification.Type.MENTION) {
builder.setStyle(new NotificationCompat.BigTextStyle()
.bigText(bodyForType(body)));
}
@ -140,7 +140,7 @@ public class NotificationHelper {
Bitmap accountAvatar;
try {
accountAvatar = Picasso.with(context)
.load(body.account.avatar)
.load(body.getAccount().getAvatar())
.transform(new RoundedTransformation(7, 0))
.get();
} catch (IOException e) {
@ -301,7 +301,7 @@ public class NotificationHelper {
return channel.getImportance() > NotificationManager.IMPORTANCE_NONE;
}
switch (notification.type) {
switch (notification.getType()) {
default:
case MENTION:
return account.getNotificationsMentioned();
@ -315,7 +315,7 @@ public class NotificationHelper {
}
private static String getChannelId(AccountEntity account, Notification notification) {
switch (notification.type) {
switch (notification.getType()) {
default:
case MENTION:
return CHANNEL_MENTION+account.getIdentifier();
@ -368,32 +368,32 @@ public class NotificationHelper {
@Nullable
private static String titleForType(Context context, Notification notification) {
switch (notification.type) {
switch (notification.getType()) {
case MENTION:
return String.format(context.getString(R.string.notification_mention_format),
notification.account.getDisplayName());
notification.getAccount().getName());
case FOLLOW:
return String.format(context.getString(R.string.notification_follow_format),
notification.account.getDisplayName());
notification.getAccount().getName());
case FAVOURITE:
return String.format(context.getString(R.string.notification_favourite_format),
notification.account.getDisplayName());
notification.getAccount().getName());
case REBLOG:
return String.format(context.getString(R.string.notification_reblog_format),
notification.account.getDisplayName());
notification.getAccount().getName());
}
return null;
}
@Nullable
private static String bodyForType(Notification notification) {
switch (notification.type) {
switch (notification.getType()) {
case FOLLOW:
return "@"+notification.account.username;
return "@"+ notification.getAccount().getUsername();
case MENTION:
case FAVOURITE:
case REBLOG:
return notification.status.content.toString();
return notification.getStatus().getContent().toString();
}
return null;
}

View File

@ -31,38 +31,38 @@ public final class ViewDataUtils {
public static StatusViewData.Concrete statusToViewData(@Nullable Status status,
boolean alwaysShowSensitiveMedia) {
if (status == null) return null;
Status visibleStatus = status.reblog == null ? status : status.reblog;
return new StatusViewData.Builder().setId(status.id)
.setAttachments(visibleStatus.attachments)
.setAvatar(visibleStatus.account.avatar)
.setContent(visibleStatus.content)
.setCreatedAt(visibleStatus.createdAt)
.setReblogsCount(visibleStatus.reblogsCount)
.setFavouritesCount(visibleStatus.favouritesCount)
.setInReplyToId(visibleStatus.inReplyToId)
.setFavourited(visibleStatus.favourited)
.setReblogged(visibleStatus.reblogged)
Status visibleStatus = status.getReblog() == null ? status : status.getReblog();
return new StatusViewData.Builder().setId(status.getId())
.setAttachments(visibleStatus.getAttachments())
.setAvatar(visibleStatus.getAccount().getAvatar())
.setContent(visibleStatus.getContent())
.setCreatedAt(visibleStatus.getCreatedAt())
.setReblogsCount(visibleStatus.getReblogsCount())
.setFavouritesCount(visibleStatus.getFavouritesCount())
.setInReplyToId(visibleStatus.getInReplyToId())
.setFavourited(visibleStatus.getFavourited())
.setReblogged(visibleStatus.getReblogged())
.setIsExpanded(false)
.setIsShowingSensitiveContent(false)
.setMentions(visibleStatus.mentions)
.setNickname(visibleStatus.account.username)
.setRebloggedAvatar(status.reblog == null ? null : status.account.avatar)
.setSensitive(visibleStatus.sensitive)
.setIsShowingSensitiveContent(alwaysShowSensitiveMedia || !visibleStatus.sensitive)
.setSpoilerText(visibleStatus.spoilerText)
.setRebloggedByUsername(status.reblog == null ? null : status.account.username)
.setUserFullName(visibleStatus.account.getDisplayName())
.setVisibility(visibleStatus.visibility)
.setSenderId(visibleStatus.account.id)
.setMentions(visibleStatus.getMentions())
.setNickname(visibleStatus.getAccount().getUsername())
.setRebloggedAvatar(status.getReblog() == null ? null : status.getAccount().getAvatar())
.setSensitive(visibleStatus.getSensitive())
.setIsShowingSensitiveContent(alwaysShowSensitiveMedia || !visibleStatus.getSensitive())
.setSpoilerText(visibleStatus.getSpoilerText())
.setRebloggedByUsername(status.getReblog() == null ? null : status.getAccount().getUsername())
.setUserFullName(visibleStatus.getAccount().getName())
.setVisibility(visibleStatus.getVisibility())
.setSenderId(visibleStatus.getAccount().getId())
.setRebloggingEnabled(visibleStatus.rebloggingAllowed())
.setApplication(visibleStatus.application)
.setEmojis(visibleStatus.emojis)
.setApplication(visibleStatus.getApplication())
.setEmojis(visibleStatus.getEmojis())
.createStatusViewData();
}
public static NotificationViewData.Concrete notificationToViewData(Notification notification, boolean alwaysShowSensitiveData) {
return new NotificationViewData.Concrete(notification.type, notification.id, notification.account,
statusToViewData(notification.status, alwaysShowSensitiveData), false);
return new NotificationViewData.Concrete(notification.getType(), notification.getId(), notification.getAccount(),
statusToViewData(notification.getStatus(), alwaysShowSensitiveData), false);
}
}

View File

@ -58,8 +58,8 @@ public abstract class StatusViewData {
private final String nickname;
private final String avatar;
private final Date createdAt;
private final String reblogsCount;
private final String favouritesCount;
private final int reblogsCount;
private final int favouritesCount;
@Nullable
private final String inReplyToId;
// I would rather have something else but it would be too much of a rewrite
@ -76,7 +76,7 @@ public abstract class StatusViewData {
@Nullable String spoilerText, Status.Visibility visibility, Attachment[] attachments,
@Nullable String rebloggedByUsername, @Nullable String rebloggedAvatar, boolean sensitive, boolean isExpanded,
boolean isShowingContent, String userFullName, String nickname, String avatar,
Date createdAt, String reblogsCount, String favouritesCount, @Nullable String inReplyToId,
Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId,
@Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled,
Status.Application application, List<Status.Emoji> emojis, @Nullable Card card) {
this.id = id;
@ -173,11 +173,11 @@ public abstract class StatusViewData {
return createdAt;
}
public String getReblogsCount() {
public int getReblogsCount() {
return reblogsCount;
}
public String getFavouritesCount() {
public int getFavouritesCount() {
return favouritesCount;
}
@ -243,8 +243,8 @@ public abstract class StatusViewData {
private String nickname;
private String avatar;
private Date createdAt;
private String reblogsCount;
private String favouritesCount;
private int reblogsCount;
private int favouritesCount;
private String inReplyToId;
private Status.Mention[] mentions;
private String senderId;
@ -364,12 +364,12 @@ public abstract class StatusViewData {
return this;
}
public Builder setReblogsCount(String reblogsCount) {
public Builder setReblogsCount(int reblogsCount) {
this.reblogsCount = reblogsCount;
return this;
}
public Builder setFavouritesCount(String favouritesCount) {
public Builder setFavouritesCount(int favouritesCount) {
this.favouritesCount = favouritesCount;
return this;
}

View File

@ -33,9 +33,9 @@
<string name="title_follow_requests">طلبات المتابعة</string>
<string name="title_edit_profile">عدل ملفك الشخصي</string>
<string name="title_saved_toot">المسودات</string>
<string name="title_x_followers"><b>%d</b> متابِعين</string>
<string name="title_x_following"><b>%d</b> مُتابَعين</string>
<string name="title_x_statuses"><b>%d</b> منشور</string>
<string name="title_x_followers"><b>%s</b> متابِعين</string>
<string name="title_x_following"><b>%s</b> مُتابَعين</string>
<string name="title_x_statuses"><b>%s</b> منشور</string>
<string name="status_username_format">\@%s</string>
<string name="status_boosted_format">%s رقّي</string>

View File

@ -33,9 +33,9 @@
<string name="title_follow_requests">Peticions de seguiment</string>
<string name="title_edit_profile">Edita el perfil</string>
<string name="title_saved_toot">Esborranys</string>
<string name="title_x_followers"><b>%d</b> seguidors</string>
<string name="title_x_following"><b>%d</b> seguint</string>
<string name="title_x_statuses"><b>%d</b> publicacions</string>
<string name="title_x_followers"><b>%s</b> seguidors</string>
<string name="title_x_following"><b>%s</b> seguint</string>
<string name="title_x_statuses"><b>%s</b> publicacions</string>
<string name="status_username_format">\@%s</string>
<string name="status_boosted_format">%s tootejat</string>

View File

@ -228,9 +228,9 @@
<string name="notification_channel_mention_name">Neue Erwähnungen</string>
<string name="replying_to">Antworten an @%s</string>
<string name="title_media">Medien</string>
<string name="title_x_followers"><b>%d</b> Folgende</string>
<string name="title_x_following"><b>%d</b> Folgt</string>
<string name="title_x_statuses"><b>%d</b> Beiträge</string>
<string name="title_x_followers"><b>%s</b> Folgende</string>
<string name="title_x_following"><b>%s</b> Folgt</string>
<string name="title_x_statuses"><b>%s</b> Beiträge</string>
<string name="load_more_placeholder_text">mehr laden</string>
<string name="dialog_reply_not_found">Fehler beim Senden des Status. Der Status, auf den du antwortest, ist vielleicht nicht mehr verfügbar. Als normale Erwähnung weiter bearbeiten?</string>
<string name="pref_default_post_privacy">Beitragssichtbarkeit</string>

View File

@ -173,9 +173,9 @@
<string name="confirmation_unblocked">Utilisateur débloqué</string>
<string name="title_x_followers"><b>%d</b> Abonnés</string>
<string name="title_x_following"><b>%d</b> Abonnements</string>
<string name="title_x_statuses"><b>%d</b> Pouets</string>
<string name="title_x_followers"><b>%s</b> Abonnés</string>
<string name="title_x_following"><b>%s</b> Abonnements</string>
<string name="title_x_statuses"><b>%s</b> Pouets</string>
<string name="status_media_hidden_title">Media caché</string>
<string name="action_hide_media">Cacher le media</string>
<string name="confirmation_unmuted">Le compte n'est plus muet</string>

View File

@ -35,9 +35,9 @@
<string name="title_follow_requests">Prośby o możliwość śledzenia</string>
<string name="title_edit_profile">Edytuj profil</string>
<string name="title_saved_toot">Szkice</string>
<string name="title_x_followers"><b>%d</b> śledzących</string>
<string name="title_x_following"><b>%d</b> śledzonych</string>
<string name="title_x_statuses"><b>%d</b> wpisów</string>
<string name="title_x_followers"><b>%s</b> śledzących</string>
<string name="title_x_following"><b>%s</b> śledzonych</string>
<string name="title_x_statuses"><b>%s</b> wpisów</string>
<string name="status_username_format">\@%s</string>

View File

@ -33,9 +33,9 @@
<string name="title_follow_requests">Solicitações de seguidor</string>
<string name="title_edit_profile">Edite seu perfil</string>
<string name="title_saved_toot">Rascunhos</string>
<string name="title_x_followers"><b>%d</b> Seguidores</string>
<string name="title_x_following"><b>%d</b> Seguindo</string>
<string name="title_x_statuses"><b>%d</b> Postagens</string>
<string name="title_x_followers"><b>%s</b> Seguidores</string>
<string name="title_x_following"><b>%s</b> Seguindo</string>
<string name="title_x_statuses"><b>%s</b> Postagens</string>
<string name="status_username_format">\@%s</string>
<string name="status_boosted_format">%s compartilhou</string>

View File

@ -33,9 +33,9 @@
<string name="title_follow_requests">Запросы на подписку</string>
<string name="title_edit_profile">Редактировать профиль</string>
<string name="title_saved_toot">Черновики</string>
<string name="title_x_followers">Подписчиков: <b>%d</b></string>
<string name="title_x_following">Подписок: <b>%d</b></string>
<string name="title_x_statuses">Постов: <b>%d</b></string>
<string name="title_x_followers">Подписчиков: <b>%s</b></string>
<string name="title_x_following">Подписок: <b>%s</b></string>
<string name="title_x_statuses">Постов: <b>%s</b></string>
<string name="status_username_format">\@%s</string>
<string name="status_boosted_format">%s продвинул(а)</string>

View File

@ -33,9 +33,9 @@
<string name="title_follow_requests">Follow Requests</string>
<string name="title_edit_profile">Edit your profile</string>
<string name="title_saved_toot">Drafts</string>
<string name="title_x_followers"><b>%d</b> Followers</string>
<string name="title_x_following"><b>%d</b> Following</string>
<string name="title_x_statuses"><b>%d</b> Posts</string>
<string name="title_x_followers"><b>%s</b> Followers</string>
<string name="title_x_following"><b>%s</b> Following</string>
<string name="title_x_statuses"><b>%s</b> Posts</string>
<string name="status_username_format">\@%s</string>
<string name="status_boosted_format">%s boosted</string>