Merge branch 'develop' into l10n_crowdin_localization

This commit is contained in:
Thomas 2017-12-09 07:59:21 +01:00 committed by GitHub
commit 3f2acebb32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 448 additions and 195 deletions

View File

@ -32,10 +32,10 @@ allprojects {
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:27.0.1'
implementation 'com.android.support:design:27.0.1'
implementation 'com.android.support:support-v4:27.0.1'
implementation 'com.android.support:recyclerview-v7:27.0.1'
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'
implementation 'com.android.support:support-v4:27.0.2'
implementation 'com.android.support:recyclerview-v7:27.0.2'
implementation 'com.github.bumptech.glide:glide:4.3.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
implementation 'com.evernote:android-job:1.2.1'
@ -44,6 +44,6 @@ dependencies {
implementation 'org.jsoup:jsoup:1.10.3'
implementation 'com.github.stom79:country-picker-android:1.2.0'
implementation 'com.github.stom79:mytransl:1.2'
safetynetImplementation 'com.google.android.gms:play-services-safetynet:11.6.0'
safetynetImplementation 'com.google.android.gms:play-services-safetynet:11.6.2'
safetynetImplementation 'io.github.kobakei:ratethisapp:1.2.0'
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -98,6 +98,7 @@ import fr.gouv.etalab.mastodon.fragments.DisplayStatusFragment;
import fr.gouv.etalab.mastodon.fragments.TabLayoutSettingsFragment;
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
import static fr.gouv.etalab.mastodon.helper.Helper.ADD_USER_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.CHANGE_THEME_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.CHANGE_USER_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT;
@ -141,6 +142,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
String show_filtered;
private AppBarLayout appBar;
private static boolean activityPaused;
private String bookmark;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -572,6 +575,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
});
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
//Get the previous bookmark value
bookmark = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, null);
Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(userId);
if( account == null){
Helper.logout(getApplicationContext());
@ -804,6 +809,44 @@ public abstract class BaseMainActivity extends AppCompatActivity
}
Helper.switchLayout(BaseMainActivity.this);
receive_data = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle b = intent.getExtras();
Helper.EventStreaming eventStreaming = (Helper.EventStreaming) intent.getSerializableExtra("eventStreaming");
assert b != null;
userIdService = b.getString("userIdService", null);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if( userIdService != null && userIdService.equals(userId)) {
if (eventStreaming == Helper.EventStreaming.NOTIFICATION) {
Notification notification = b.getParcelable("data");
if (notificationsFragment != null) {
notificationsFragment.refresh(notification);
}
} else if (eventStreaming == Helper.EventStreaming.UPDATE) {
Status status = b.getParcelable("data");
if (homeFragment != null) {
homeFragment.refresh(status);
}
} else if (eventStreaming == Helper.EventStreaming.DELETE) {
//noinspection unused
String id = b.getString("id");
if (notificationsFragment != null) {
//noinspection StatementWithEmptyBody
if (notificationsFragment.getUserVisibleHint()) {
} else {
}
}
}
updateNotifCounter();
updateHomeCounter();
}
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
// Retrieves instance
new RetrieveInstanceAsyncTask(getApplicationContext(), BaseMainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -984,6 +1027,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
if( !toolbar_search.isIconified() ) {
toolbar_search.setIconified(true);
}
}else if (extras.getInt(INTENT_ACTION) == ADD_USER_INTENT){
this.recreate();
}
}else if( Intent.ACTION_SEND.equals(action) && type != null ) {
if ("text/plain".equals(type)) {
@ -1142,43 +1187,7 @@ public abstract class BaseMainActivity extends AppCompatActivity
}
}
};
receive_data = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle b = intent.getExtras();
Helper.EventStreaming eventStreaming = (Helper.EventStreaming) intent.getSerializableExtra("eventStreaming");
assert b != null;
userIdService = b.getString("userIdService", null);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if( userIdService != null && userIdService.equals(userId)) {
if (eventStreaming == Helper.EventStreaming.NOTIFICATION) {
Notification notification = b.getParcelable("data");
if (notificationsFragment != null) {
notificationsFragment.refresh(notification);
}
} else if (eventStreaming == Helper.EventStreaming.UPDATE) {
Status status = b.getParcelable("data");
if (homeFragment != null) {
homeFragment.refresh(status);
}
} else if (eventStreaming == Helper.EventStreaming.DELETE) {
//noinspection unused
String id = b.getString("id");
if (notificationsFragment != null) {
//noinspection StatementWithEmptyBody
if (notificationsFragment.getUserVisibleHint()) {
} else {
}
}
}
updateNotifCounter();
updateHomeCounter();
}
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
LocalBroadcastManager.getInstance(this).registerReceiver(receive_federated_data, new IntentFilter(Helper.RECEIVE_FEDERATED_DATA));
LocalBroadcastManager.getInstance(this).registerReceiver(receive_local_data, new IntentFilter(Helper.RECEIVE_LOCAL_DATA));
}
@ -1194,8 +1203,6 @@ public abstract class BaseMainActivity extends AppCompatActivity
stopService(streamingIntent);
editor.apply();
}
if( receive_data != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
if( receive_federated_data != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_federated_data);
if( receive_local_data != null)
@ -1211,6 +1218,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
@Override
public void onDestroy(){
super.onDestroy();
if( receive_data != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
}
@SuppressWarnings("StatementWithEmptyBody")
@ -1392,6 +1401,14 @@ public abstract class BaseMainActivity extends AppCompatActivity
Helper.canPin = (currentVersion.compareTo(minVersion) == 1 || currentVersion.equals(minVersion));
}
public String getBookmark() {
return bookmark;
}
public void setBookmark(@SuppressWarnings("SameParameterValue") String bookmark) {
this.bookmark = bookmark;
}
/**
* Page Adapter for settings
@ -1572,4 +1589,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
}
startService(streamingIntent);
}
public DisplayStatusFragment getHomeFragment(){
return homeFragment;
}
}

View File

@ -39,6 +39,8 @@ import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@ -69,7 +71,8 @@ public class InstanceHealthActivity extends AppCompatActivity {
private InstanceSocial instanceSocial;
private TextView name, values, checked_at, up, uptime;
private String instance;
private LinearLayout container;
private LinearLayout container, instance_container;
private RelativeLayout loader;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -92,7 +95,8 @@ public class InstanceHealthActivity extends AppCompatActivity {
up = findViewById(R.id.up);
uptime = findViewById(R.id.uptime);
container = findViewById(R.id.container);
instance_container = findViewById(R.id.instance_container);
loader = findViewById(R.id.loader);
close.setOnClickListener(new View.OnClickListener() {
@Override
@ -177,6 +181,8 @@ public class InstanceHealthActivity extends AppCompatActivity {
uptime.setText(String.format("Uptime: %.2f %%", (instanceSocial.getUptime()*100)));
checked_at.setText(String.format("Checked at: %s", Helper.dateToString(getApplicationContext(), instanceSocial.getChecked_at())));
values.setText(String.format("version: %s \n %s users - %s statuses", instanceSocial.getVersion(), withSuffix(instanceSocial.getUsers()), withSuffix(instanceSocial.getStatuses())));
instance_container.setVisibility(View.VISIBLE);
loader.setVisibility(View.GONE);
}
});

View File

@ -379,10 +379,21 @@ public class MediaActivity extends AppCompatActivity implements OnDownloadInterf
}
@Override
public void onDownloaded(String path, Error error) {
public void onDownloaded(String path, String originUrl, Error error) {
File response = new File(path);
File dir = getCacheDir();
File from = new File(dir, response.getName());
File to = new File(dir, Helper.md5(originUrl) + ".mp4");
if (from.exists())
//noinspection ResultOfMethodCallIgnored
from.renameTo(to);
fileVideo = to;
downloadedImage = null;
progress.setVisibility(View.GONE);
Uri uri = Uri.parse(to.getAbsolutePath());
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(path));
videoView.setVideoURI(uri);
videoView.start();
MediaController mc = new MediaController(MediaActivity.this);
videoView.setMediaController(mc);

View File

@ -1260,7 +1260,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}
@Override
public void onDownloaded(String pathToFile, Error error) {
public void onDownloaded(String pathToFile, String url, Error error) {
picture_scrollview.setVisibility(View.VISIBLE);
Bitmap pictureMention = BitmapFactory.decodeFile(pathToFile);
ByteArrayOutputStream bos = new ByteArrayOutputStream();

View File

@ -76,7 +76,7 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask<Void, Void, Void> {
protected void onPostExecute(Void result) {
Intent mainActivity = new Intent(this.contextReference.get(), MainActivity.class);
mainActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mainActivity.putExtra(Helper.INTENT_ACTION, Helper.ADD_USER_INTENT);
this.contextReference.get().startActivity(mainActivity);
((Activity) this.contextReference.get()).finish();

View File

@ -45,6 +45,7 @@ import com.bumptech.glide.request.transition.Transition;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import fr.gouv.etalab.mastodon.activities.HashTagActivity;
@ -93,6 +94,7 @@ public class Status implements Parcelable {
private boolean isNew = false;
private boolean isTakingScreenShot = false;
private boolean isVisible = true;
private boolean fetchMore = false;
private Status status;
private String content, contentCW, contentTranslated;
private SpannableString contentSpan, contentSpanCW, contentSpanTranslated;
@ -476,23 +478,6 @@ public class Status implements Parcelable {
public void makeEmojis(final Context context, final OnRetrieveEmojiInterface listener){
final SpannableString spannableStringContent;
final SpannableString spannableStringCW;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
spannableStringContent = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getContent():status.getContent(), Html.FROM_HTML_MODE_LEGACY));
else
//noinspection deprecation
spannableStringContent = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getContent():status.getContent()));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
spannableStringCW = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getSpoiler_text():status.getSpoiler_text(), Html.FROM_HTML_MODE_LEGACY));
else
//noinspection deprecation
spannableStringCW = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getSpoiler_text():status.getSpoiler_text()));
final List<Emojis> emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
if( emojis != null && emojis.size() > 0 ) {
@ -511,8 +496,6 @@ public class Status implements Parcelable {
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
i[0]++;
if( i[0] == (emojis.size())) {
status.setContentSpan(spannableStringContent);
status.setContentSpanCW(spannableStringCW);
listener.onRetrieveEmoji(status,false);
}
return false;
@ -522,22 +505,22 @@ public class Status implements Parcelable {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (spannableStringContent.toString().contains(targetedEmoji)) {
if (contentSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = spannableStringContent.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
for (int startPosition = -1; (startPosition = contentSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
spannableStringContent.setSpan(
contentSpan.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
if (spannableStringCW.toString().contains(targetedEmoji)) {
if (contentSpanCW.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = spannableStringCW.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
for (int startPosition = -1; (startPosition = contentSpanCW.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
spannableStringCW.setSpan(
contentSpanCW.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
@ -546,8 +529,6 @@ public class Status implements Parcelable {
}
i[0]++;
if( i[0] == (emojis.size())) {
status.setContentSpan(spannableStringContent);
status.setContentSpanCW(spannableStringCW);
listener.onRetrieveEmoji(status, false);
}
}
@ -753,4 +734,20 @@ public class Status implements Parcelable {
public void setEmojiTranslateFound(boolean emojiTranslateFound) {
isEmojiTranslateFound = emojiTranslateFound;
}
public boolean isFetchMore() {
return fetchMore;
}
public void setFetchMore(boolean fetchMore) {
this.fetchMore = fetchMore;
}
@Override
public boolean equals(Object otherStatus) {
return otherStatus != null && (otherStatus == this || otherStatus instanceof Status && this.getId().equals(((Status) otherStatus).getId()));
}
}

View File

@ -228,12 +228,12 @@ public class HttpsConnection {
if(context instanceof TootActivity)
((TootActivity)context).runOnUiThread(new Runnable() {
public void run() {
listener.onDownloaded(saveFilePath, null);
listener.onDownloaded(saveFilePath, downloadUrl, null);
}});
if(context instanceof MediaActivity)
((MediaActivity)context).runOnUiThread(new Runnable() {
public void run() {
listener.onDownloaded(saveFilePath, null);
listener.onDownloaded(saveFilePath, downloadUrl,null);
}});
} else {
final Error error = new Error();
@ -241,12 +241,12 @@ public class HttpsConnection {
if(context instanceof TootActivity)
((TootActivity)context).runOnUiThread(new Runnable() {
public void run() {
listener.onDownloaded(null, error);
listener.onDownloaded(null, downloadUrl, error);
}});
if(context instanceof MediaActivity)
((MediaActivity)context).runOnUiThread(new Runnable() {
public void run() {
listener.onDownloaded(null, error);
listener.onDownloaded(null,downloadUrl, error);
}});
}

View File

@ -259,6 +259,8 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
holder.status_reblog_count.setText(String.valueOf(status.getReblogs_count()));
holder.status_date.setText(Helper.dateDiff(context, status.getCreated_at()));
Helper.absoluteDateTimeReveal(context, holder.status_date, status.getCreated_at());
//Adds attachment -> disabled, to enable them uncomment the line below
//loadAttachments(status, holder);
holder.notification_status_container.setVisibility(View.VISIBLE);

View File

@ -185,6 +185,8 @@ public class SearchListAdapter extends BaseAdapter {
holder.status_content.setAutoLinkMask(Linkify.WEB_URLS);
holder.status_toot_date.setText(Helper.dateDiff(context, status.getCreated_at()));
Helper.absoluteDateTimeReveal(context, holder.status_toot_date, status.getCreated_at());
Glide.with(holder.status_account_profile.getContext())
.load(ppurl)
.into(holder.status_account_profile);

View File

@ -71,6 +71,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.activities.BaseMainActivity;
import fr.gouv.etalab.mastodon.activities.MediaActivity;
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
import fr.gouv.etalab.mastodon.activities.ShowConversationActivity;
@ -84,6 +85,7 @@ import fr.gouv.etalab.mastodon.client.Entities.Attachment;
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.client.Entities.Status;
import fr.gouv.etalab.mastodon.fragments.DisplayStatusFragment;
import fr.gouv.etalab.mastodon.helper.CrossActions;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
@ -114,6 +116,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
private final int DISPLAYED_STATUS = 1;
private List<Status> pins;
private int conversationPosition;
private String bookmark = null;
public StatusListAdapter(Context context, RetrieveFeedsAsyncTask.Type type, String targetedId, boolean isOnWifi, int behaviorWithAttachments, int translator, List<Status> statuses){
super();
@ -127,6 +130,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
this.targetedId = targetedId;
this.translator = translator;
pins = new ArrayList<>();
if( context instanceof BaseMainActivity){
bookmark = ((BaseMainActivity) context).getBookmark();
}
}
public StatusListAdapter(Context context, int position, String targetedId, boolean isOnWifi, int behaviorWithAttachments, int translator, List<Status> statuses){
@ -141,6 +147,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
this.targetedId = targetedId;
this.translator = translator;
pins = new ArrayList<>();
if( context instanceof BaseMainActivity){
bookmark = ((BaseMainActivity) context).getBookmark();
}
}
@Override
@ -218,7 +227,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
LinearLayout status_replies;
LinearLayout status_replies_profile_pictures;
ProgressBar loader_replies;
Button fetch_more;
ImageView new_element;
public View getView(){
@ -228,6 +237,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
ViewHolder(View itemView) {
super(itemView);
loader_replies = itemView.findViewById(R.id.loader_replies);
fetch_more = itemView.findViewById(R.id.fetch_more);
status_document_container = itemView.findViewById(R.id.status_document_container);
status_content = itemView.findViewById(R.id.status_content);
status_content_translated = itemView.findViewById(R.id.status_content_translated);
@ -267,7 +277,6 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
status_replies_profile_pictures = itemView.findViewById(R.id.status_replies_profile_pictures);
new_element = itemView.findViewById(R.id.new_element);
status_action_container = itemView.findViewById(R.id.status_action_container);
}
}
@ -559,7 +568,25 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
//-------- END -> Change the color in gray for accounts in DARK Theme only
if( status.isFetchMore()) {
holder.fetch_more.setVisibility(View.VISIBLE);
holder.fetch_more.setEnabled(true);
}else {
holder.fetch_more.setVisibility(View.GONE);
}
holder.fetch_more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
status.setFetchMore(false);
holder.fetch_more.setEnabled(false);
holder.fetch_more.setVisibility(View.GONE);
DisplayStatusFragment homeFragment = ((BaseMainActivity) context).getHomeFragment();
if( homeFragment != null)
homeFragment.fetchMore(status.getId());
}
});
if( status.getReblog() == null)
holder.status_favorite_count.setText(String.valueOf(status.getFavourites_count()));
@ -572,6 +599,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
holder.status_toot_date.setText(Helper.dateDiff(context, status.getCreated_at()));
Helper.absoluteDateTimeReveal(context, holder.status_toot_date, status.getCreated_at());
if( status.getReblog() != null) {
Glide.with(holder.status_account_profile_boost.getContext())
@ -1145,7 +1173,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
private void loadAttachments(final Status status, ViewHolder holder){
private void loadAttachments(final Status status, final ViewHolder holder){
List<Attachment> attachments = status.getMedia_attachments();
if( attachments != null && attachments.size() > 0){
int i = 0;
@ -1231,6 +1259,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
holder.status_document_container.setVisibility(View.GONE);
}
holder.status_show_more.setVisibility(View.GONE);
}
@ -1388,4 +1418,5 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
public void onRetrieveSearchEmoji(List<Emojis> emojis) {
}
}

View File

@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.List;
import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.activities.BaseMainActivity;
import fr.gouv.etalab.mastodon.activities.MainActivity;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveMissingFeedsAsyncTask;
import fr.gouv.etalab.mastodon.client.APIResponse;
@ -68,11 +69,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
private String tag;
private boolean swiped;
private RecyclerView lv_status;
private boolean isOnWifi;
private int behaviorWithAttachments;
private boolean showMediaOnly, showPinned;
private int positionSpinnerTrans;
private String lastReadStatus;
private Intent streamingFederatedIntent, streamingLocalIntent;
LinearLayoutManager mLayoutManager;
@ -101,13 +98,10 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
assert context != null;
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
isOnWifi = Helper.isOnWIFI(context);
positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
boolean isOnWifi = Helper.isOnWIFI(context);
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer);
behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if( type == RetrieveFeedsAsyncTask.Type.HOME)
lastReadStatus = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, null);
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
lv_status = rootView.findViewById(R.id.lv_status);
mainLoader = rootView.findViewById(R.id.loader);
nextElementLoader = rootView.findViewById(R.id.loading_next_status);
@ -155,12 +149,15 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
flag_loading = true;
swiped = true;
MainActivity.countNewStatus = 0;
if( context instanceof BaseMainActivity){
((BaseMainActivity) context).setBookmark(null);
}
if( type == RetrieveFeedsAsyncTask.Type.USER)
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, showPinned, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, null, showMediaOnly, showPinned, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else if( type == RetrieveFeedsAsyncTask.Type.TAG)
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
asyncTask = new RetrieveFeedsAsyncTask(context, type, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4,
@ -173,6 +170,16 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if( type == RetrieveFeedsAsyncTask.Type.HOME ){
String bookmark;
if( context instanceof BaseMainActivity){
bookmark = ((BaseMainActivity) context).getBookmark();
if( bookmark != null) {
new RetrieveFeedsAsyncTask(context, RetrieveFeedsAsyncTask.Type.ONESTATUS, bookmark,null, false,false, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
asyncTask = new RetrieveFeedsAsyncTask(context, type, bookmark, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
}
}
}else {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@ -185,6 +192,16 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if( type == RetrieveFeedsAsyncTask.Type.HOME ){
String bookmark;
if( context instanceof BaseMainActivity){
bookmark = ((BaseMainActivity) context).getBookmark();
if( bookmark != null) {
new RetrieveFeedsAsyncTask(context, RetrieveFeedsAsyncTask.Type.ONESTATUS, bookmark,null, false,false, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
asyncTask = new RetrieveFeedsAsyncTask(context, type, bookmark, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
}
}
}
}
@ -242,6 +259,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
textviewNoAction.setVisibility(View.VISIBLE);
else
textviewNoAction.setVisibility(View.GONE);
if( swiped ){
if (previousPosition > 0) {
for (int i = 0; i < previousPosition; i++) {
@ -253,20 +271,53 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
}
if( statuses != null && statuses.size() > 0) {
if( type == RetrieveFeedsAsyncTask.Type.FAVOURITES ){
this.statuses.addAll(statuses);
}else {
for (Status tmpStatus : statuses) {
if (this.statuses.size() == 0 || Long.parseLong(tmpStatus.getId()) < Long.parseLong(this.statuses.get(this.statuses.size() - 1).getId())) {
if (type == RetrieveFeedsAsyncTask.Type.HOME && firstLoad && lastReadStatus != null && Long.parseLong(tmpStatus.getId()) > Long.parseLong(lastReadStatus)) {
if (type == RetrieveFeedsAsyncTask.Type.HOME) {
String bookmark = null;
if( context instanceof BaseMainActivity){
bookmark = ((BaseMainActivity) context).getBookmark();
}
//Toots are older than the bookmark -> no special treatment with them
if( bookmark == null || Long.parseLong(statuses.get(0).getId()) < Long.parseLong(bookmark)){
this.statuses.addAll(statuses);
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
}else { //Toots are younger than the bookmark
int lastLoop = 0;
for (Status tmpStatus : statuses) {
//Mark status at new ones when their id is greater than the bookmark id / Also increments counter
if (Long.parseLong(tmpStatus.getId()) > Long.parseLong(bookmark)) {
tmpStatus.setNew(true);
MainActivity.countNewStatus++;
} else {
tmpStatus.setNew(false);
}
this.statuses.add(tmpStatus);
//Put the toot at its place in the list (id desc)
if (this.statuses != null) {
int loop = 0;
while (loop < this.statuses.size() && Long.parseLong(tmpStatus.getId()) < Long.parseLong(this.statuses.get(loop).getId())) {
loop++;
}
if(Long.parseLong(statuses.get(0).getId()) != Long.parseLong(bookmark) ) {
if( !this.statuses.contains(tmpStatus) ) { //Element not already addeds
this.statuses.add(loop, tmpStatus);
statusListAdapter.notifyItemInserted(loop);
if (Long.parseLong(tmpStatus.getId()) > Long.parseLong(bookmark) && loop > lastLoop)
lastLoop = loop; //Record the last position of the inserted toot in this.statuses
}
}
}
}
if (Long.parseLong(statuses.get((statuses.size() - 1)).getId()) > Long.parseLong(bookmark)) {
statuses.get(statuses.size() - 1).setFetchMore(true);
}
if( lastLoop > 0 ) //Moves to the bookmark
lv_status.scrollToPosition((lastLoop));
}
}else {
this.statuses.addAll(statuses);
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
}
if( firstLoad && type == RetrieveFeedsAsyncTask.Type.HOME && statuses.size() > 0) {
//Update the id of the last toot retrieved
@ -275,9 +326,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
editor.apply();
lastReadStatus = statuses.get(0).getId();
}
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
if( firstLoad && type == RetrieveFeedsAsyncTask.Type.HOME)
//Display new value in counter
try {
@ -397,7 +446,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
SharedPreferences.Editor editor = sharedpreferences.edit();
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
lastReadStatus = statuses.get(0).getId();
editor.apply();
} else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC ){
if (visible) {
@ -473,7 +521,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
SharedPreferences.Editor editor = sharedpreferences.edit();
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
lastReadStatus = statuses.get(0).getId();
editor.apply();
}
}
@ -506,4 +553,8 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
}catch (Exception ignored){}
}
}
public void fetchMore(String max_id){
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

View File

@ -21,10 +21,12 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.CountDownTimer;
import android.support.annotation.Nullable;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.app.AlertDialog;
@ -60,12 +62,10 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.util.DisplayMetrics;
import android.util.Patterns;
import android.view.Menu;
@ -105,6 +105,7 @@ import java.io.OutputStream;
import java.net.InetAddress;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@ -189,6 +190,7 @@ public class Helper {
public static final int HOME_TIMELINE_INTENT = 2;
public static final int CHANGE_THEME_INTENT = 3;
public static final int CHANGE_USER_INTENT = 4;
public static final int ADD_USER_INTENT = 5;
//Settings
public static final String SET_TOOTS_PER_PAGE = "set_toots_per_page";
public static final String SET_ACCOUNTS_PER_PAGE = "set_accounts_per_page";
@ -479,6 +481,56 @@ public class Helper {
return date;
}
/**
* Converts a Date date into a date-time string (SHORT format for both)
* @param context
* @param date to be converted
* @return String
*/
public static String shortDateTime(Context context, Date date) {
Locale userLocale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
userLocale = context.getResources().getConfiguration().getLocales().get(0);
} else {
//noinspection deprecation
userLocale = context.getResources().getConfiguration().locale;
}
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, userLocale);
return df.format(date);
}
/**
* Makes the tvDate TextView field clickable, and displays the absolute date & time of a toot
* for 5 seconds.
* @param context Context
* @param tvDate TextView
* @param date Date
*/
public static void absoluteDateTimeReveal(final Context context, final TextView tvDate, final Date date) {
tvDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tvDate.setText(Helper.shortDateTime(context, date));
new CountDownTimer((5 * 1000), 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
tvDate.setText(Helper.dateDiff(context, date));
}
}.start();
}
});
}
/**
* Check if WIFI is opened
* @param context Context
@ -737,10 +789,24 @@ public class Helper {
Uri uri = Uri.parse("file://" + file.getAbsolutePath());
intent.setDataAndType(uri, getMimeType(url));
Glide.with(context)
.asBitmap()
.load(preview_url)
.listener(new RequestListener<Bitmap>(){
@Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
notify_user(context, intent, notificationIdTmp, BitmapFactory.decodeResource(context.getResources(),
R.mipmap.ic_launcher), context.getString(R.string.save_over), context.getString(R.string.download_from, fileName));
Toast.makeText(context, R.string.toast_saved,Toast.LENGTH_LONG).show();
return false;
}
})
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {

View File

@ -21,6 +21,6 @@ import fr.gouv.etalab.mastodon.client.Entities.Error;
* Interface when a media has been downloaded
*/
public interface OnDownloadInterface {
void onDownloaded(String saveFilePath, Error error);
void onDownloaded(String saveFilePath, String downloadUrl, Error error);
void onUpdateProgress(int progress);
}

View File

@ -163,7 +163,8 @@ public class LiveNotificationService extends IntentService {
httpsURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpsURLConnection.setRequestProperty("Keep-Alive", "header");
httpsURLConnection.setRequestProperty("Connection", "close");
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
httpsURLConnection.setRequestMethod("GET");
httpsURLConnection.setConnectTimeout(70000);
httpsURLConnection.setReadTimeout(70000);
@ -211,7 +212,7 @@ public class LiveNotificationService extends IntentService {
try {
JSONObject eventJson = new JSONObject(event);
onRetrieveStreaming(eventStreaming, account, eventJson);
} catch (JSONException ignored) {}
} catch (JSONException ignored) {ignored.printStackTrace();}
}
}
}else {
@ -253,7 +254,6 @@ public class LiveNotificationService extends IntentService {
fr.gouv.etalab.mastodon.client.Entities.Status status ;
final Notification notification;
String dataId = null;
Bundle b = new Bundle();
if( event == Helper.EventStreaming.NOTIFICATION){
notification = API.parseNotificationResponse(getApplicationContext(), response);

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
</vector>

View File

@ -10,74 +10,94 @@
android:layout_width="match_parent"
android:layout_height="300dp">
<TextView
android:id="@+id/name"
android:textSize="20sp"
android:textColor="@color/titleb"
android:layout_gravity="center"
<LinearLayout
android:id="@+id/instance_container"
android:visibility="gone"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/name"
android:textSize="20sp"
android:textColor="@color/titleb"
android:layout_gravity="center"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/values"
android:textColor="@color/dark_text"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:textColor="@color/dark_text"
android:layout_marginTop="10dp"
android:id="@+id/checked_at"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/up"
android:layout_marginTop="10dp"
android:textSize="16sp"
android:textStyle="bold"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:textColor="@color/dark_text"
android:id="@+id/uptime"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_marginTop="10dp"
android:id="@+id/ref_instance"
android:layout_gravity="end|center_vertical"
android:text="via instances.social"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
tools:ignore="HardcodedText" />
<Button
android:layout_marginTop="20dp"
android:id="@+id/close"
android:textSize="16sp"
android:layout_gravity="center"
android:textAllCaps="false"
android:text="@string/close"
android:textColor="@color/buttonb"
style="@style/Base.Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/values"
android:textColor="@color/dark_text"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:textColor="@color/dark_text"
android:layout_marginTop="10dp"
android:id="@+id/checked_at"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/up"
android:layout_marginTop="10dp"
android:textSize="16sp"
android:textStyle="bold"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:textColor="@color/dark_text"
android:id="@+id/uptime"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_marginTop="10dp"
android:id="@+id/ref_instance"
android:layout_gravity="end|center_vertical"
android:text="via instances.social"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
tools:ignore="HardcodedText" />
<Button
android:layout_marginTop="20dp"
android:id="@+id/close"
android:textSize="16sp"
android:layout_gravity="center"
android:textAllCaps="false"
android:text="@string/close"
android:textColor="@color/buttonb"
style="@style/Base.Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
</LinearLayout>

View File

@ -433,4 +433,20 @@
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
<Button
android:id="@+id/fetch_more"
android:visibility="gone"
android:textAllCaps="false"
android:drawableLeft="@drawable/ic_expand_more"
android:drawableStart="@drawable/ic_expand_more"
android:gravity="center"
android:layout_gravity="center"
android:drawablePadding="5dp"
android:textStyle="bold"
android:textSize="16sp"
android:maxLines="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Base.Widget.AppCompat.Button.Borderless"
android:text="@string/fetch_more_toots" />
</LinearLayout>

View File

@ -444,4 +444,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -420,4 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -401,4 +401,5 @@
<string name="filter_regex">Mit regulären Ausdrücken filtern</string>
<string name="search">Suche</string>
<string name="delete">Löschen</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -411,4 +411,5 @@
<string name="filter_regex">Filtrer avec une expression rationnelle</string>
<string name="search">Rechercher</string>
<string name="delete">Supprimer</string>
<string name="fetch_more_toots">Afficher plus de pouets…</string>
</resources>

View File

@ -428,4 +428,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -404,4 +404,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -404,4 +404,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -404,4 +404,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Wegfilteren met reguliere expressies</string>
<string name="search">Zoeken</string>
<string name="delete">Verwijderen</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,4 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -420,4 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -409,7 +409,7 @@
<string name="thanks_text_dev">
Agradecimentos a:
</string>
<string name="filter_regex">Filtrar com uma expressão regular</string>
<string name="filter_regex">Filtrar com uma expressão regular</string>
<string name="search">Pesquisar</string>
<string name="delete">Eliminar</string>
<string name="fetch_more_toots">Fetch more toots…</string>

View File

@ -416,5 +416,5 @@ Vă mulțumesc:
<string name="filter_regex">Filtrează expresii usuale</string>
<string name="search">Căutare</string>
<string name="delete">Șterge</string>
<string name="fetch_more_toots">Fetch more toots…</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -420,5 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -420,5 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -412,5 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -102,7 +102,7 @@
<string name="fav_removed">Modül favorilerden kaldırıldı!</string>
<string name="reblog_added">Modül arttırıldı!</string>
<string name="reblog_removed">Modül artık arttırılmış değil!</string>
<string name="reblog_by">%d%% hızlandırıldı</string>
<string name="reblog_by">%1$s hızlandırıldı</string>
<string name="favourite_add">Bu modülü favorilere ekleyin?</string>
<string name="favourite_remove">Bu modülü favorilerden kaldırın?</string>
<string name="reblog_add">Bu modülü arttır?</string>
@ -369,7 +369,7 @@ Lütfen, almak istediğiniz itme bildirimlerini onaylayın.
<string name="privacy_data">
Hesaplardan yalnızca temel bilgiler cihazda saklanır.
         Bu veriler kesinlikle gizlidir ve yalnızca uygulama tarafından kullanılabilir.
         Uygulamanın silinmesi, bu verileri derhal kaldırır. \ N
         Uygulamanın silinmesi, bu verileri derhal kaldırır. \n
         ⚠ Oturum açma ve parolalar asla saklanmaz. Yalnızca bir örneğe sahip güvenli bir kimlik doğrulama (SSL) sırasında kullanılırlar. </string>
<string name="privacy_authorizations_title">Izinler:</string>
<string name="privacy_authorizations">
@ -395,7 +395,7 @@ Uygulama <b> izleme araçları kullanmaz </b>(kitle ölçümü, hata raporlama,
         - <b> Gson </b>: Taslaklar kaydetmek için </string>
<string name="privacy_API_yandex_title">Modül tercümesi</string>
<string name="privacy_API_yandex_authorizations">
Uygulama cihazın yerel ayarını ve Yandex API\'sini kullanarak toots çevirme olanağı sunar. \ N
Uygulama cihazın yerel ayarını ve Yandex API\'sini kullanarak toots çevirme olanağı sunar. \n
         Yandex\'in şu adreste bulunabilecek uygun gizlilik politikası vardır: https://yandex.ru/legal/confidential/?lang=en </string>
<string name="thanks_text">
Stephane\'a logo için teşekkür ederiz. </string>
@ -404,5 +404,5 @@ Teşekkürler: </string>
<string name="filter_regex">Düzenli ifadelerle filtreleme</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -420,5 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -404,4 +404,5 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -398,4 +398,5 @@
<string name="filter_regex">按正则表达式进行筛选</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>

View File

@ -447,4 +447,6 @@
<string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string>
<string name="delete">Delete</string>
<string name="fetch_more_toots">Fetch more toots…</string>
</resources>