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 { dependencies {
implementation 'com.android.support:appcompat-v7:27.0.1' implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.1' implementation 'com.android.support:design:27.0.2'
implementation 'com.android.support:support-v4:27.0.1' implementation 'com.android.support:support-v4:27.0.2'
implementation 'com.android.support:recyclerview-v7:27.0.1' implementation 'com.android.support:recyclerview-v7:27.0.2'
implementation 'com.github.bumptech.glide:glide:4.3.1' implementation 'com.github.bumptech.glide:glide:4.3.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
implementation 'com.evernote:android-job:1.2.1' implementation 'com.evernote:android-job:1.2.1'
@ -44,6 +44,6 @@ dependencies {
implementation 'org.jsoup:jsoup:1.10.3' implementation 'org.jsoup:jsoup:1.10.3'
implementation 'com.github.stom79:country-picker-android:1.2.0' implementation 'com.github.stom79:country-picker-android:1.2.0'
implementation 'com.github.stom79:mytransl:1.2' 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' 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.fragments.TabLayoutSettingsFragment;
import fr.gouv.etalab.mastodon.sqlite.AccountDAO; 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_THEME_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.CHANGE_USER_INTENT; import static fr.gouv.etalab.mastodon.helper.Helper.CHANGE_USER_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_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; String show_filtered;
private AppBarLayout appBar; private AppBarLayout appBar;
private static boolean activityPaused; private static boolean activityPaused;
private String bookmark;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -572,6 +575,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
}); });
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); 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); Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(userId);
if( account == null){ if( account == null){
Helper.logout(getApplicationContext()); Helper.logout(getApplicationContext());
@ -804,6 +809,44 @@ public abstract class BaseMainActivity extends AppCompatActivity
} }
Helper.switchLayout(BaseMainActivity.this); 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 // Retrieves instance
new RetrieveInstanceAsyncTask(getApplicationContext(), BaseMainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new RetrieveInstanceAsyncTask(getApplicationContext(), BaseMainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@ -984,6 +1027,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
if( !toolbar_search.isIconified() ) { if( !toolbar_search.isIconified() ) {
toolbar_search.setIconified(true); toolbar_search.setIconified(true);
} }
}else if (extras.getInt(INTENT_ACTION) == ADD_USER_INTENT){
this.recreate();
} }
}else if( Intent.ACTION_SEND.equals(action) && type != null ) { }else if( Intent.ACTION_SEND.equals(action) && type != null ) {
if ("text/plain".equals(type)) { 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_federated_data, new IntentFilter(Helper.RECEIVE_FEDERATED_DATA));
LocalBroadcastManager.getInstance(this).registerReceiver(receive_local_data, new IntentFilter(Helper.RECEIVE_LOCAL_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); stopService(streamingIntent);
editor.apply(); editor.apply();
} }
if( receive_data != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
if( receive_federated_data != null) if( receive_federated_data != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_federated_data); LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_federated_data);
if( receive_local_data != null) if( receive_local_data != null)
@ -1211,6 +1218,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
@Override @Override
public void onDestroy(){ public void onDestroy(){
super.onDestroy(); super.onDestroy();
if( receive_data != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
} }
@SuppressWarnings("StatementWithEmptyBody") @SuppressWarnings("StatementWithEmptyBody")
@ -1392,6 +1401,14 @@ public abstract class BaseMainActivity extends AppCompatActivity
Helper.canPin = (currentVersion.compareTo(minVersion) == 1 || currentVersion.equals(minVersion)); 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 * Page Adapter for settings
@ -1572,4 +1589,8 @@ public abstract class BaseMainActivity extends AppCompatActivity
} }
startService(streamingIntent); startService(streamingIntent);
} }
public DisplayStatusFragment getHomeFragment(){
return homeFragment;
}
} }

View File

@ -39,6 +39,8 @@ import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
@ -69,7 +71,8 @@ public class InstanceHealthActivity extends AppCompatActivity {
private InstanceSocial instanceSocial; private InstanceSocial instanceSocial;
private TextView name, values, checked_at, up, uptime; private TextView name, values, checked_at, up, uptime;
private String instance; private String instance;
private LinearLayout container; private LinearLayout container, instance_container;
private RelativeLayout loader;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -92,7 +95,8 @@ public class InstanceHealthActivity extends AppCompatActivity {
up = findViewById(R.id.up); up = findViewById(R.id.up);
uptime = findViewById(R.id.uptime); uptime = findViewById(R.id.uptime);
container = findViewById(R.id.container); container = findViewById(R.id.container);
instance_container = findViewById(R.id.instance_container);
loader = findViewById(R.id.loader);
close.setOnClickListener(new View.OnClickListener() { close.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -177,6 +181,8 @@ public class InstanceHealthActivity extends AppCompatActivity {
uptime.setText(String.format("Uptime: %.2f %%", (instanceSocial.getUptime()*100))); uptime.setText(String.format("Uptime: %.2f %%", (instanceSocial.getUptime()*100)));
checked_at.setText(String.format("Checked at: %s", Helper.dateToString(getApplicationContext(), instanceSocial.getChecked_at()))); 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()))); 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 @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); progress.setVisibility(View.GONE);
Uri uri = Uri.parse(to.getAbsolutePath());
videoView.setVisibility(View.VISIBLE); videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(path)); videoView.setVideoURI(uri);
videoView.start(); videoView.start();
MediaController mc = new MediaController(MediaActivity.this); MediaController mc = new MediaController(MediaActivity.this);
videoView.setMediaController(mc); videoView.setMediaController(mc);

View File

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

View File

@ -76,7 +76,7 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask<Void, Void, Void> {
protected void onPostExecute(Void result) { protected void onPostExecute(Void result) {
Intent mainActivity = new Intent(this.contextReference.get(), MainActivity.class); 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); this.contextReference.get().startActivity(mainActivity);
((Activity) this.contextReference.get()).finish(); ((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.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import fr.gouv.etalab.mastodon.activities.HashTagActivity; import fr.gouv.etalab.mastodon.activities.HashTagActivity;
@ -93,6 +94,7 @@ public class Status implements Parcelable {
private boolean isNew = false; private boolean isNew = false;
private boolean isTakingScreenShot = false; private boolean isTakingScreenShot = false;
private boolean isVisible = true; private boolean isVisible = true;
private boolean fetchMore = false;
private Status status; private Status status;
private String content, contentCW, contentTranslated; private String content, contentCW, contentTranslated;
private SpannableString contentSpan, contentSpanCW, contentSpanTranslated; private SpannableString contentSpan, contentSpanCW, contentSpanTranslated;
@ -476,23 +478,6 @@ public class Status implements Parcelable {
public void makeEmojis(final Context context, final OnRetrieveEmojiInterface listener){ 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(); final List<Emojis> emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
if( emojis != null && emojis.size() > 0 ) { 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) { public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
i[0]++; i[0]++;
if( i[0] == (emojis.size())) { if( i[0] == (emojis.size())) {
status.setContentSpan(spannableStringContent);
status.setContentSpanCW(spannableStringCW);
listener.onRetrieveEmoji(status,false); listener.onRetrieveEmoji(status,false);
} }
return false; return false;
@ -522,22 +505,22 @@ public class Status implements Parcelable {
@Override @Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) { public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":"; 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 //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(); final int endPosition = startPosition + targetedEmoji.length();
spannableStringContent.setSpan( contentSpan.setSpan(
new ImageSpan(context, new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context), Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition, (int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); 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 //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(); final int endPosition = startPosition + targetedEmoji.length();
spannableStringCW.setSpan( contentSpanCW.setSpan(
new ImageSpan(context, new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context), Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition, (int) Helper.convertDpToPixel(20, context), false)), startPosition,
@ -546,8 +529,6 @@ public class Status implements Parcelable {
} }
i[0]++; i[0]++;
if( i[0] == (emojis.size())) { if( i[0] == (emojis.size())) {
status.setContentSpan(spannableStringContent);
status.setContentSpanCW(spannableStringCW);
listener.onRetrieveEmoji(status, false); listener.onRetrieveEmoji(status, false);
} }
} }
@ -753,4 +734,20 @@ public class Status implements Parcelable {
public void setEmojiTranslateFound(boolean emojiTranslateFound) { public void setEmojiTranslateFound(boolean emojiTranslateFound) {
isEmojiTranslateFound = 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) if(context instanceof TootActivity)
((TootActivity)context).runOnUiThread(new Runnable() { ((TootActivity)context).runOnUiThread(new Runnable() {
public void run() { public void run() {
listener.onDownloaded(saveFilePath, null); listener.onDownloaded(saveFilePath, downloadUrl, null);
}}); }});
if(context instanceof MediaActivity) if(context instanceof MediaActivity)
((MediaActivity)context).runOnUiThread(new Runnable() { ((MediaActivity)context).runOnUiThread(new Runnable() {
public void run() { public void run() {
listener.onDownloaded(saveFilePath, null); listener.onDownloaded(saveFilePath, downloadUrl,null);
}}); }});
} else { } else {
final Error error = new Error(); final Error error = new Error();
@ -241,12 +241,12 @@ public class HttpsConnection {
if(context instanceof TootActivity) if(context instanceof TootActivity)
((TootActivity)context).runOnUiThread(new Runnable() { ((TootActivity)context).runOnUiThread(new Runnable() {
public void run() { public void run() {
listener.onDownloaded(null, error); listener.onDownloaded(null, downloadUrl, error);
}}); }});
if(context instanceof MediaActivity) if(context instanceof MediaActivity)
((MediaActivity)context).runOnUiThread(new Runnable() { ((MediaActivity)context).runOnUiThread(new Runnable() {
public void run() { 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_reblog_count.setText(String.valueOf(status.getReblogs_count()));
holder.status_date.setText(Helper.dateDiff(context, status.getCreated_at())); 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 //Adds attachment -> disabled, to enable them uncomment the line below
//loadAttachments(status, holder); //loadAttachments(status, holder);
holder.notification_status_container.setVisibility(View.VISIBLE); 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_content.setAutoLinkMask(Linkify.WEB_URLS);
holder.status_toot_date.setText(Helper.dateDiff(context, status.getCreated_at())); 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()) Glide.with(holder.status_account_profile.getContext())
.load(ppurl) .load(ppurl)
.into(holder.status_account_profile); .into(holder.status_account_profile);

View File

@ -71,6 +71,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import fr.gouv.etalab.mastodon.R; 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.MediaActivity;
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity; import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
import fr.gouv.etalab.mastodon.activities.ShowConversationActivity; 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.Emojis;
import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.client.Entities.Status; 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.CrossActions;
import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface; 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 final int DISPLAYED_STATUS = 1;
private List<Status> pins; private List<Status> pins;
private int conversationPosition; 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){ public StatusListAdapter(Context context, RetrieveFeedsAsyncTask.Type type, String targetedId, boolean isOnWifi, int behaviorWithAttachments, int translator, List<Status> statuses){
super(); super();
@ -127,6 +130,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
this.targetedId = targetedId; this.targetedId = targetedId;
this.translator = translator; this.translator = translator;
pins = new ArrayList<>(); 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){ 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.targetedId = targetedId;
this.translator = translator; this.translator = translator;
pins = new ArrayList<>(); pins = new ArrayList<>();
if( context instanceof BaseMainActivity){
bookmark = ((BaseMainActivity) context).getBookmark();
}
} }
@Override @Override
@ -218,7 +227,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
LinearLayout status_replies; LinearLayout status_replies;
LinearLayout status_replies_profile_pictures; LinearLayout status_replies_profile_pictures;
ProgressBar loader_replies; ProgressBar loader_replies;
Button fetch_more;
ImageView new_element; ImageView new_element;
public View getView(){ public View getView(){
@ -228,6 +237,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
loader_replies = itemView.findViewById(R.id.loader_replies); 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_document_container = itemView.findViewById(R.id.status_document_container);
status_content = itemView.findViewById(R.id.status_content); status_content = itemView.findViewById(R.id.status_content);
status_content_translated = itemView.findViewById(R.id.status_content_translated); 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); status_replies_profile_pictures = itemView.findViewById(R.id.status_replies_profile_pictures);
new_element = itemView.findViewById(R.id.new_element); new_element = itemView.findViewById(R.id.new_element);
status_action_container = itemView.findViewById(R.id.status_action_container); 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 //-------- 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) if( status.getReblog() == null)
holder.status_favorite_count.setText(String.valueOf(status.getFavourites_count())); 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())); 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) { if( status.getReblog() != null) {
Glide.with(holder.status_account_profile_boost.getContext()) 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(); List<Attachment> attachments = status.getMedia_attachments();
if( attachments != null && attachments.size() > 0){ if( attachments != null && attachments.size() > 0){
int i = 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_document_container.setVisibility(View.GONE);
} }
holder.status_show_more.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) { public void onRetrieveSearchEmoji(List<Emojis> emojis) {
} }
} }

View File

@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import fr.gouv.etalab.mastodon.R; 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.activities.MainActivity;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveMissingFeedsAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveMissingFeedsAsyncTask;
import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.APIResponse;
@ -68,11 +69,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
private String tag; private String tag;
private boolean swiped; private boolean swiped;
private RecyclerView lv_status; private RecyclerView lv_status;
private boolean isOnWifi;
private int behaviorWithAttachments;
private boolean showMediaOnly, showPinned; private boolean showMediaOnly, showPinned;
private int positionSpinnerTrans;
private String lastReadStatus;
private Intent streamingFederatedIntent, streamingLocalIntent; private Intent streamingFederatedIntent, streamingLocalIntent;
LinearLayoutManager mLayoutManager; LinearLayoutManager mLayoutManager;
@ -101,13 +98,10 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
assert context != null; assert context != null;
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
isOnWifi = Helper.isOnWIFI(context); boolean isOnWifi = Helper.isOnWIFI(context);
positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX); int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer); swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer);
behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS); int 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);
lv_status = rootView.findViewById(R.id.lv_status); lv_status = rootView.findViewById(R.id.lv_status);
mainLoader = rootView.findViewById(R.id.loader); mainLoader = rootView.findViewById(R.id.loader);
nextElementLoader = rootView.findViewById(R.id.loading_next_status); nextElementLoader = rootView.findViewById(R.id.loading_next_status);
@ -155,12 +149,15 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
flag_loading = true; flag_loading = true;
swiped = true; swiped = true;
MainActivity.countNewStatus = 0; MainActivity.countNewStatus = 0;
if( context instanceof BaseMainActivity){
((BaseMainActivity) context).setBookmark(null);
}
if( type == RetrieveFeedsAsyncTask.Type.USER) 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) 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 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, 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); asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else { else {
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 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 { }else {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { 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); asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else { else {
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 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); textviewNoAction.setVisibility(View.VISIBLE);
else else
textviewNoAction.setVisibility(View.GONE); textviewNoAction.setVisibility(View.GONE);
if( swiped ){ if( swiped ){
if (previousPosition > 0) { if (previousPosition > 0) {
for (int i = 0; i < previousPosition; i++) { 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( statuses != null && statuses.size() > 0) {
if( type == RetrieveFeedsAsyncTask.Type.FAVOURITES ){ if (type == RetrieveFeedsAsyncTask.Type.HOME) {
this.statuses.addAll(statuses); String bookmark = null;
}else { if( context instanceof BaseMainActivity){
for (Status tmpStatus : statuses) { bookmark = ((BaseMainActivity) context).getBookmark();
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)) {
//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); tmpStatus.setNew(true);
MainActivity.countNewStatus++; 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) { if( firstLoad && type == RetrieveFeedsAsyncTask.Type.HOME && statuses.size() > 0) {
//Update the id of the last toot retrieved //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); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId()); editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
editor.apply(); editor.apply();
lastReadStatus = statuses.get(0).getId();
} }
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
if( firstLoad && type == RetrieveFeedsAsyncTask.Type.HOME) if( firstLoad && type == RetrieveFeedsAsyncTask.Type.HOME)
//Display new value in counter //Display new value in counter
try { try {
@ -397,7 +446,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
SharedPreferences.Editor editor = sharedpreferences.edit(); SharedPreferences.Editor editor = sharedpreferences.edit();
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId()); editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
lastReadStatus = statuses.get(0).getId();
editor.apply(); editor.apply();
} else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC ){ } else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC ){
if (visible) { if (visible) {
@ -473,7 +521,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
SharedPreferences.Editor editor = sharedpreferences.edit(); SharedPreferences.Editor editor = sharedpreferences.edit();
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId()); editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
lastReadStatus = statuses.get(0).getId();
editor.apply(); editor.apply();
} }
} }
@ -506,4 +553,8 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
}catch (Exception ignored){} }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.Activity;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.graphics.BitmapFactory;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuffXfermode;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.os.CountDownTimer;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.app.AlertDialog; 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.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.text.Html; import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.style.ClickableSpan; import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Patterns; import android.util.Patterns;
import android.view.Menu; import android.view.Menu;
@ -105,6 +105,7 @@ import java.io.OutputStream;
import java.net.InetAddress; import java.net.InetAddress;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
@ -189,6 +190,7 @@ public class Helper {
public static final int HOME_TIMELINE_INTENT = 2; public static final int HOME_TIMELINE_INTENT = 2;
public static final int CHANGE_THEME_INTENT = 3; public static final int CHANGE_THEME_INTENT = 3;
public static final int CHANGE_USER_INTENT = 4; public static final int CHANGE_USER_INTENT = 4;
public static final int ADD_USER_INTENT = 5;
//Settings //Settings
public static final String SET_TOOTS_PER_PAGE = "set_toots_per_page"; public static final String SET_TOOTS_PER_PAGE = "set_toots_per_page";
public static final String SET_ACCOUNTS_PER_PAGE = "set_accounts_per_page"; public static final String SET_ACCOUNTS_PER_PAGE = "set_accounts_per_page";
@ -479,6 +481,56 @@ public class Helper {
return date; 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 * Check if WIFI is opened
* @param context Context * @param context Context
@ -737,10 +789,24 @@ public class Helper {
Uri uri = Uri.parse("file://" + file.getAbsolutePath()); Uri uri = Uri.parse("file://" + file.getAbsolutePath());
intent.setDataAndType(uri, getMimeType(url)); intent.setDataAndType(uri, getMimeType(url));
Glide.with(context) Glide.with(context)
.asBitmap() .asBitmap()
.load(preview_url) .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>() { .into(new SimpleTarget<Bitmap>() {
@Override @Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) { 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 * Interface when a media has been downloaded
*/ */
public interface OnDownloadInterface { public interface OnDownloadInterface {
void onDownloaded(String saveFilePath, Error error); void onDownloaded(String saveFilePath, String downloadUrl, Error error);
void onUpdateProgress(int progress); void onUpdateProgress(int progress);
} }

View File

@ -163,7 +163,8 @@ public class LiveNotificationService extends IntentService {
httpsURLConnection.setRequestProperty("Connection", "Keep-Alive"); httpsURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpsURLConnection.setRequestProperty("Keep-Alive", "header"); httpsURLConnection.setRequestProperty("Keep-Alive", "header");
httpsURLConnection.setRequestProperty("Connection", "close"); 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.setRequestMethod("GET");
httpsURLConnection.setConnectTimeout(70000); httpsURLConnection.setConnectTimeout(70000);
httpsURLConnection.setReadTimeout(70000); httpsURLConnection.setReadTimeout(70000);
@ -211,7 +212,7 @@ public class LiveNotificationService extends IntentService {
try { try {
JSONObject eventJson = new JSONObject(event); JSONObject eventJson = new JSONObject(event);
onRetrieveStreaming(eventStreaming, account, eventJson); onRetrieveStreaming(eventStreaming, account, eventJson);
} catch (JSONException ignored) {} } catch (JSONException ignored) {ignored.printStackTrace();}
} }
} }
}else { }else {
@ -253,7 +254,6 @@ public class LiveNotificationService extends IntentService {
fr.gouv.etalab.mastodon.client.Entities.Status status ; fr.gouv.etalab.mastodon.client.Entities.Status status ;
final Notification notification; final Notification notification;
String dataId = null; String dataId = null;
Bundle b = new Bundle(); Bundle b = new Bundle();
if( event == Helper.EventStreaming.NOTIFICATION){ if( event == Helper.EventStreaming.NOTIFICATION){
notification = API.parseNotificationResponse(getApplicationContext(), response); 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_width="match_parent"
android:layout_height="300dp"> android:layout_height="300dp">
<TextView <LinearLayout
android:id="@+id/name" android:id="@+id/instance_container"
android:textSize="20sp" android:visibility="gone"
android:textColor="@color/titleb" android:orientation="vertical"
android:layout_gravity="center" 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:gravity="center"
android:layout_width="wrap_content" >
android:layout_height="wrap_content" /> <ProgressBar
android:layout_width="wrap_content"
<TextView android:layout_height="wrap_content"
android:id="@+id/values" android:indeterminate="true" />
android:textColor="@color/dark_text" </RelativeLayout>
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> </LinearLayout>

View File

@ -433,4 +433,20 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"/> android:layout_weight="1"/>
</LinearLayout> </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> </LinearLayout>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -409,7 +409,7 @@
<string name="thanks_text_dev"> <string name="thanks_text_dev">
Agradecimentos a: Agradecimentos a:
</string> </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="search">Pesquisar</string>
<string name="delete">Eliminar</string> <string name="delete">Eliminar</string>
<string name="fetch_more_toots">Fetch more toots…</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="filter_regex">Filtrează expresii usuale</string>
<string name="search">Căutare</string> <string name="search">Căutare</string>
<string name="delete">Șterge</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> </resources>

View File

@ -420,5 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string> <string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="delete">Delete</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> </resources>

View File

@ -420,5 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string> <string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="delete">Delete</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> </resources>

View File

@ -412,5 +412,5 @@
<string name="filter_regex">Filter out by regular expressions</string> <string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="delete">Delete</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> </resources>

View File

@ -102,7 +102,7 @@
<string name="fav_removed">Modül favorilerden kaldırıldı!</string> <string name="fav_removed">Modül favorilerden kaldırıldı!</string>
<string name="reblog_added">Modül arttı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_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_add">Bu modülü favorilere ekleyin?</string>
<string name="favourite_remove">Bu modülü favorilerden kaldırın?</string> <string name="favourite_remove">Bu modülü favorilerden kaldırın?</string>
<string name="reblog_add">Bu modülü arttır?</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"> <string name="privacy_data">
Hesaplardan yalnızca temel bilgiler cihazda saklanır. Hesaplardan yalnızca temel bilgiler cihazda saklanır.
         Bu veriler kesinlikle gizlidir ve yalnızca uygulama tarafından kullanılabilir.          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>          ⚠ 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_title">Izinler:</string>
<string name="privacy_authorizations"> <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>          - <b> Gson </b>: Taslaklar kaydetmek için </string>
<string name="privacy_API_yandex_title">Modül tercümesi</string> <string name="privacy_API_yandex_title">Modül tercümesi</string>
<string name="privacy_API_yandex_authorizations"> <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>          Yandex\'in şu adreste bulunabilecek uygun gizlilik politikası vardır: https://yandex.ru/legal/confidential/?lang=en </string>
<string name="thanks_text"> <string name="thanks_text">
Stephane\'a logo için teşekkür ederiz. </string> 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="filter_regex">Düzenli ifadelerle filtreleme</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="delete">Delete</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> </resources>

View File

@ -420,5 +420,5 @@
<string name="filter_regex">Filter out by regular expressions</string> <string name="filter_regex">Filter out by regular expressions</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="delete">Delete</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> </resources>

View File

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

View File

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

View File

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