Merge pull request #28 from stom79/develop

Release 1.5.8
This commit is contained in:
Thomas 2017-11-07 19:07:37 +01:00 committed by GitHub
commit 948900d9b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 237 additions and 116 deletions

View File

@ -1,7 +1,15 @@
## Mastalab is a multi-accounts client for Mastodon
## Mastalab is a multi-accounts client for Mastodon [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
The number of libraries is minimized and it does not use tracking tools. The source code is free (GPLv3). Any help would be greatly appreciated to fix spelling or for any other suggestions.
[<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=fr.gouv.etalab.mastodon)
[<img alt='Get it on Google Play' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/app/fr.gouv.etalab.mastodon)
[Release notes](https://github.com/stom79/mastalab/releases)
### Features
**Multi-accounts management**

View File

@ -7,8 +7,8 @@ android {
applicationId "fr.gouv.etalab.mastodon"
minSdkVersion 15
targetSdkVersion 26
versionCode 67
versionName "1.5.7"
versionCode 68
versionName "1.5.8"
}
flavorDimensions "default"
buildTypes {
@ -43,7 +43,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.0'
implementation 'org.jsoup:jsoup:1.10.3'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.github.stom79:country-picker-android:1.2.0-beta-1'
implementation 'com.github.stom79:country-picker-android:1.2.0'
safetynetImplementation 'com.google.android.gms:play-services-safetynet:11.4.2'
safetynetImplementation 'io.github.kobakei:ratethisapp:1.2.0'
}

View File

@ -809,7 +809,7 @@ public abstract class BaseMainActivity extends AppCompatActivity
});
// Asked once for notification opt-in
boolean popupShown = sharedpreferences.getBoolean(Helper.SET_POPUP_PUSH, false);
if(!popupShown){
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(BaseMainActivity.this);

View File

@ -30,11 +30,11 @@ import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.URLUtil;
import android.widget.ImageView;
import android.widget.MediaController;
@ -100,6 +100,8 @@ public class MediaActivity extends AppCompatActivity {
private File fileVideo;
private TextView progress;
private boolean canSwipe;
private enum actionSwipe{
RIGHT_TO_LEFT,
LEFT_TO_RIGHT,
@ -113,9 +115,9 @@ public class MediaActivity extends AppCompatActivity {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
if( theme == Helper.THEME_LIGHT){
setTheme(R.style.AppTheme);
setTheme(R.style.AppTheme_NoActionBar);
}else {
setTheme(R.style.AppThemeDark);
setTheme(R.style.AppThemeDark_NoActionBar);
}
setContentView(R.layout.activity_media);
attachments = getIntent().getParcelableArrayListExtra("mediaArray");
@ -123,14 +125,60 @@ public class MediaActivity extends AppCompatActivity {
mediaPosition = getIntent().getExtras().getInt("position", 1);
if( attachments == null || attachments.size() == 0)
finish();
if( getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
RelativeLayout main_container_media = findViewById(R.id.main_container_media);
if( theme == Helper.THEME_LIGHT){
main_container_media.setBackgroundResource(R.color.mastodonC2);
}else {
main_container_media.setBackgroundResource(R.color.mastodonC1);
main_container_media.setBackgroundResource(R.color.mastodonC1_);
}
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if( getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(android.content.Context.LAYOUT_INFLATER_SERVICE);
assert inflater != null;
@SuppressLint("InflateParams") View view = inflater.inflate(R.layout.picture_actionbar, null);
getSupportActionBar().setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView action_save = getSupportActionBar().getCustomView().findViewById(R.id.action_save);
ImageView close = getSupportActionBar().getCustomView().findViewById(R.id.close);
if( close != null){
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
action_save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(Build.VERSION.SDK_INT >= 23 ){
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(MediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_REQUEST_CODE);
} else {
Helper.manageMoveFileDownload(MediaActivity.this, preview_url, finalUrlDownload, downloadedImage, fileVideo);
}
}else{
Helper.manageMoveFileDownload(MediaActivity.this, preview_url, finalUrlDownload, downloadedImage, fileVideo);
}
}
});
Handler h = new Handler();
h.postDelayed(new Runnable() {
@Override
public void run() {
// DO DELAYED STUFF
if(canSwipe)
getSupportActionBar().hide();
}
}, 2000);
}
@ -160,6 +208,9 @@ public class MediaActivity extends AppCompatActivity {
@Override
public void onMatrixChanged(RectF rect) {
canSwipe = (imageView.getScale() == 1 );
if( !canSwipe && getSupportActionBar() != null && getSupportActionBar().isShowing()){
getSupportActionBar().hide();
}
}
});
@ -183,36 +234,6 @@ public class MediaActivity extends AppCompatActivity {
displayMediaAtPosition(actionSwipe.POP);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_download:
if(Build.VERSION.SDK_INT >= 23 ){
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(MediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_REQUEST_CODE);
} else {
Helper.manageMoveFileDownload(MediaActivity.this, preview_url, finalUrlDownload, downloadedImage, fileVideo);
}
}else{
Helper.manageMoveFileDownload(MediaActivity.this, preview_url, finalUrlDownload, downloadedImage, fileVideo);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_media, menu);
return true;
}
/**
* Manage touch event
@ -222,6 +243,19 @@ public class MediaActivity extends AppCompatActivity {
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if( event.getAction() == MotionEvent.ACTION_DOWN){
if( getSupportActionBar() != null && !getSupportActionBar().isShowing() && canSwipe) {
getSupportActionBar().show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
getSupportActionBar().hide();
}
}, 2000);
}
}
if( !canSwipe || mediaPosition > attachments.size() || mediaPosition < 1 || attachments.size() <= 1)
return super.dispatchTouchEvent(event);
switch(event.getAction()){
@ -396,15 +430,10 @@ public class MediaActivity extends AppCompatActivity {
filename = url;
if( attachments.size() > 1 )
filename = String.format("%s (%s/%s)",filename, mediaPosition, attachments.size());
LayoutInflater mInflater = LayoutInflater.from(MediaActivity.this);
ActionBar actionBar = getSupportActionBar();
if( actionBar != null){
@SuppressLint("InflateParams") View picture_actionbar = mInflater.inflate(R.layout.picture_actionbar, null);
TextView picture_actionbar_title = picture_actionbar.findViewById(R.id.picture_actionbar);
TextView picture_actionbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
picture_actionbar_title.setText(filename);
actionBar.setCustomView(picture_actionbar);
actionBar.setDisplayShowCustomEnabled(true);
}else {
setTitle(url);
}

View File

@ -312,10 +312,12 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
if( isOwner) {
popup.getMenu().findItem(R.id.action_block).setVisible(false);
popup.getMenu().findItem(R.id.action_mute).setVisible(false);
popup.getMenu().findItem(R.id.action_mention).setVisible(false);
stringArrayConf = getResources().getStringArray(R.array.more_action_owner_confirm);
}else {
popup.getMenu().findItem(R.id.action_block).setVisible(true);
popup.getMenu().findItem(R.id.action_mute).setVisible(true);
popup.getMenu().findItem(R.id.action_mention).setVisible(true);
stringArrayConf = getResources().getStringArray(R.array.more_action_confirm);
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@ -349,6 +351,13 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
startActivity(intent);
}
return true;
case R.id.action_mention:
Intent intent = new Intent(getApplicationContext(), TootActivity.class);
Bundle b = new Bundle();
b.putString("mentionAccount", account.getAcct());
intent.putExtras(b);
startActivity(intent);
return true;
case R.id.action_mute:
builderInner = new AlertDialog.Builder(ShowAccountActivity.this);
builderInner.setTitle(stringArrayConf[0]);

View File

@ -74,10 +74,10 @@ import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import com.github.stom79.localepicker.CountryPicker;
import com.github.stom79.localepicker.CountryPickerListener;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.BinaryHttpResponseHandler;
import com.mukesh.countrypicker.CountryPicker;
import com.mukesh.countrypicker.CountryPickerListener;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
@ -192,6 +192,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
private View popup_trans;
private AlertDialog dialogTrans;
private AlertDialog alertDialogEmoji;
private String mentionAccount;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -289,6 +290,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
sharedContent = b.getString("sharedContent", null);
sharedContentIni = b.getString("sharedContent", null);
sharedSubject = b.getString("sharedSubject", null);
mentionAccount = b.getString("mentionAccount", null);
restoredScheduled = b.getBoolean("restoredScheduled", false);
// ACTION_SEND route
if (b.getInt("uriNumber", 0) == 1) {
@ -307,7 +309,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}
restored = b.getLong("restored", -1);
}
initialContent = toot_content.getText().toString();
if(restoredScheduled){
toot_it.setVisibility(View.GONE);
invalidateOptionsMenu();
@ -327,6 +329,11 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
else
userId = accountReply.getId();
if( mentionAccount != null){
toot_content.setText(String.format("@%s\n", mentionAccount));
toot_content.setSelection(toot_content.getText().length());
toot_space_left.setText(String.valueOf(toot_content.length()));
}
if( tootMention != null && urlMention != null && fileMention != null) {
Bitmap pictureMention = BitmapFactory.decodeFile(getCacheDir() + "/" + fileMention);
if (pictureMention != null) {
@ -342,6 +349,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
toot_content.setText(String.format("\n\nvia @%s\n\n%s\n\n", tootMention, urlMention));
toot_space_left.setText(String.valueOf(toot_content.length()));
}
initialContent = toot_content.getText().toString();
Account account;
if( accountReply == null)
account = new AccountDAO(getApplicationContext(),db).getAccountByID(userId);
@ -525,7 +533,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
public void onClick(View v) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if (ContextCompat.checkSelfPermission(TootActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(TootActivity.this,
@ -535,21 +542,17 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}
}
Intent intent;
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
String[] mimetypes = {"image/*", "video/*"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(intent, PICK_IMAGE);
}else {
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
getIntent.setType("image/*");
intent.setType("image/* video/*");
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(getIntent, getString(R.string.toot_select_image));
Intent chooserIntent = Intent.createChooser(intent, getString(R.string.toot_select_image));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
startActivityForResult(chooserIntent, PICK_IMAGE);
}
@ -812,7 +815,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
picker.setListener(new CountryPickerListener() {
@SuppressLint("InflateParams")
@Override
public void onSelectCountry(String name, String code, String dialCode, String locale, int flagDrawableResID) {
public void onSelectCountry(String name, String locale, int flagDrawableResID) {
picker.dismiss();
AlertDialog.Builder transAlert = new AlertDialog.Builder(TootActivity.this);
transAlert.setTitle(R.string.translate_toot);
@ -1704,6 +1707,10 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}
//If toot is not restored
if( restored == -1 ){
if( tootReply.getSpoiler_text() != null && tootReply.getSpoiler_text().length() > 0) {
toot_cw_content.setText(tootReply.getSpoiler_text());
toot_cw_content.setVisibility(View.VISIBLE);
}
//Retrieves mentioned accounts + OP and adds them at the beginin of the toot
ArrayList<String> mentionedAccountsAdded = new ArrayList<>();
if( tootReply.getAccount() != null && tootReply.getAccount().getAcct() != null && !tootReply.getAccount().getId().equals(userId)) {
@ -1719,12 +1726,13 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}
}
}
toot_content.setText(toot_content.getText().toString().trim());
if (toot_content.getText().toString().startsWith("@")) {
//Put a "<trim>dot<space>" at the end of all mentioned account to force capitalization
toot_content.append("\n");
}
toot_space_left.setText(String.valueOf(toot_content.length()));
toot_content.requestFocus();
toot_content.setSelection(toot_content.getText().length()); //Put cursor at the end
}
initialContent = toot_content.getText().toString();
@ -1736,7 +1744,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
//Nothing to store here....
if(toot_content.getText().toString().trim().length() == 0 && (attachments == null || attachments.size() <1) && toot_cw_content.getText().toString().trim().length() == 0)
return;
if( initialContent.equals(toot_content.getText().toString()))
if( initialContent.trim().equals(toot_content.getText().toString().trim()))
return;
Status toot = new Status();
toot.setSensitive(isSensitive);

View File

@ -24,6 +24,7 @@ import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveNotificationsInterface;
/**
* Created by Thomas on 28/04/2017.
* Retrieves notifications on the instance
@ -57,7 +58,6 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask<Void, Void, Void>
@Override
protected Void doInBackground(Void... params) {
API api = new API(this.contextReference.get(), instance, token);
if( acct == null)
apiResponse = api.getNotifications(max_id, display);

View File

@ -16,7 +16,6 @@ package fr.gouv.etalab.mastodon.client;
import android.content.Context;
import android.content.SharedPreferences;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpClient;
@ -1222,22 +1221,22 @@ public class API {
params.put("max_id", max_id);
if( since_id != null )
params.put("since_id", since_id);
if( 0 > limit || limit > 40)
limit = 40;
if( 0 > limit || limit > 30)
limit = 30;
params.put("limit",String.valueOf(limit));
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean notif_follow, notif_add, notif_mention, notif_share;
if( !display) {
notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
}else {
if( display) {
notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW_FILTER, true);
notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD_FILTER, true);
notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION_FILTER, true);
notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE_FILTER, true);
}else{
notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
}
if( !notif_follow )
params.add("exclude_types[]", "follow");

View File

@ -300,7 +300,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
holder.status_document_container.setVisibility(View.GONE);
holder.notification_status_content.setVisibility(View.VISIBLE);
holder.status_show_more.setVisibility(View.GONE);
holder.status_action_container.setVisibility(View.GONE);
holder.status_action_container.setVisibility(View.INVISIBLE);
}else {
holder.status_action_container.setVisibility(View.VISIBLE);
@ -591,7 +591,6 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
notificationsListAdapter.notifyDataSetChanged();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Bitmap bitmap = Helper.convertTootIntoBitmap(context, holder.getView());
@ -618,7 +617,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
context.startActivity(intent);
}
}, 1000);
}, 500);
return true;
default:
return true;

View File

@ -607,7 +607,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
holder.status_content_container.setVisibility(View.VISIBLE);
holder.status_translate.setVisibility(View.GONE);
holder.status_show_more.setVisibility(View.GONE);
holder.status_action_container.setVisibility(View.GONE);
holder.status_action_container.setVisibility(View.INVISIBLE);
}else {
holder.status_action_container.setVisibility(View.VISIBLE);
if( trans_forced || (translator != Helper.TRANS_NONE && currentLocale != null && status.getLanguage() != null && !status.getLanguage().trim().equals(currentLocale))){
@ -1052,9 +1052,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
case R.id.action_mention:
status.setTakingScreenShot(true);
statusListAdapter.notifyDataSetChanged();
Handler handler = new Handler();
// Get a handler that can be used to post to the main thread
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Bitmap bitmap = Helper.convertTootIntoBitmap(context, holder.getView());
@ -1080,8 +1080,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
intent.putExtras(b);
context.startActivity(intent);
}
}, 1000);
}, 500);
return true;
default:
return true;

View File

@ -260,7 +260,18 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
flag_loading = true;
swiped = true;
MainActivity.countNewNotifications = 0;
asyncTask = new RetrieveNotificationsAsyncTask(context, true, null, null, max_id, null, null, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if( context != null)
asyncTask = new RetrieveNotificationsAsyncTask(context, true, null, null, max_id, null, null, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
if( context != null){
asyncTask = new RetrieveNotificationsAsyncTask(context, true, null, null, max_id, null, null, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
}, 500);
}
}

View File

@ -124,7 +124,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
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.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
mainLoader = rootView.findViewById(R.id.loader);
nextElementLoader = rootView.findViewById(R.id.loading_next_status);
textviewNoAction = rootView.findViewById(R.id.no_action);

View File

@ -1696,7 +1696,7 @@ public class Helper {
paint.setStrokeWidth(12);
paint.setTextSize(30);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
canvas.drawText("Via #Mastalab", view.getWidth()-230, view.getHeight() - 5, paint);
canvas.drawText("Via #Mastalab", view.getWidth()-230, view.getHeight() -50, paint);
if( new_element != null)
new_element.setVisibility(new_element_v);

View File

@ -36,6 +36,7 @@ import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -87,7 +88,6 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
.setPeriodic(TimeUnit.MINUTES.toMillis(Helper.MINUTES_BETWEEN_NOTIFICATIONS_REFRESH), TimeUnit.MINUTES.toMillis(5))
.setUpdateCurrent(updateCurrent)
.setRequiredNetworkType(JobRequest.NetworkType.METERED)
.setRequiresBatteryNotLow(true)
.setRequirementsEnforced(false)
.build()
.schedule();
@ -107,11 +107,10 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
//Check which notifications the user wants to see
boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
boolean notif_ask = sharedpreferences.getBoolean(Helper.SET_NOTIF_ASK, true);
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
//User disagree with all notifications
if( !notif_follow && !notif_add && !notif_ask && !notif_mention && !notif_share)
if( !notif_follow && !notif_add && !notif_mention && !notif_share)
return; //Nothing is done
//No account connected, the service is stopped
if(!Helper.isLoggedIn(getContext()))
@ -124,8 +123,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
return;
//Retrieve users in db that owner has.
for (Account account: accounts) {
String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId(), null);
new RetrieveNotificationsAsyncTask(getContext(), false, account.getInstance(), account.getToken(), max_id, account.getAcct(), account.getId(), NotificationsSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new RetrieveNotificationsAsyncTask(getContext(), false, account.getInstance(), account.getToken(), null, account.getAcct(), account.getId(), NotificationsSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
}
@ -134,31 +132,34 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
@Override
public void onRetrieveNotifications(APIResponse apiResponse, String acct, final String userId, boolean refreshData) {
final List<Notification> notifications = apiResponse.getNotifications();
if( apiResponse.getError() != null || notifications == null || notifications.size() == 0)
List<Notification> notificationsReceived = apiResponse.getNotifications();
if( apiResponse.getError() != null || notificationsReceived == null || notificationsReceived.size() == 0)
return;
Bitmap icon_notification = null;
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
final String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + userId, null);
final List<Notification> notifications = new ArrayList<>();
int pos = 0;
for(Notification notif: notificationsReceived){
if( max_id == null || Long.parseLong(notif.getId()) > Long.parseLong(max_id) ) {
notifications.add(pos, notif);
pos++;
}
}
if( notifications.size() == 0 )
return;
//No previous notifications in cache, so no notification will be sent
int newFollows = 0;
int newAdds = 0;
int newAsks = 0;
int newMentions = 0;
int newShare = 0;
String notificationUrl = null;
String title = null;
final String message;
for(Notification notification: notifications){
//The notification associated to max_id is discarded as it is supposed to have already been sent
if( max_id != null && notification.getId().equals(max_id))
continue;
switch (notification.getType()){
case "mention":
if(notif_mention){
@ -213,7 +214,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
}
}
int allNotifCount = newFollows + newAdds + newAsks + newMentions + newShare;
int allNotifCount = newFollows + newAdds + newMentions + newShare;
if( allNotifCount > 0){
//Some others notification
int other = allNotifCount -1;
@ -227,8 +228,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
intent.putExtra(PREF_KEY_ID, userId);
long notif_id = Long.parseLong(userId);
final int notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
if( notificationUrl != null && icon_notification == null){
if( notificationUrl != null ){
ImageLoader imageLoaderNoty = ImageLoader.getInstance();
File cacheDir = new File(getContext().getCacheDir(), getContext().getString(R.string.app_name));
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getContext())
@ -247,8 +247,9 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
if( max_id != null) {
notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, message);
notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, message);
String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + userId, null);
if( lastNotif == null || Long.parseLong(notifications.get(0).getId()) > Long.parseLong(lastNotif)){
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notifications.get(0).getId());
editor.apply();
@ -256,9 +257,10 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
}
@Override
public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){
if( max_id != null) {
notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.mastodonlogo), finalTitle, message);
notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.mastodonlogo), finalTitle, message);
String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + userId, null);
if( lastNotif == null || Long.parseLong(notifications.get(0).getId()) > Long.parseLong(lastNotif)){
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notifications.get(0).getId());
editor.apply();

View File

@ -19,8 +19,22 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main_container_media"
>
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_container_media">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"
>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="@style/AppThemeDark_NoActionBar"
app:popupTheme="?attr/popupOverlay"/>
</android.support.design.widget.AppBarLayout>
<com.github.chrisbanes.photoview.PhotoView
android:visibility="gone"
android:layout_centerInParent="true"

View File

@ -21,6 +21,9 @@
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_container"
android:divider="?android:dividerHorizontal"
android:showDividers="end"
android:paddingTop="5dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"

View File

@ -15,17 +15,53 @@
You should have received a copy of the GNU General Public License along with Mastalab; if not,
see <http://www.gnu.org/licenses>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar"
android:contentInsetLeft="0dp"
android:contentInsetStart="0dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
android:contentInsetRight="0dp"
android:contentInsetEnd="0dp"
app:contentInsetRight="0dp"
app:contentInsetEnd="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
android:background="?attr/colorPrimary"
app:popupTheme="?attr/popupOverlay"
tools:ignore="UnusedAttribute">
<ImageView
android:id="@+id/close"
android:src="@drawable/ic_close"
android:layout_width="30dp"
android:layout_height="30dp"
android:gravity="center_vertical"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_gravity="center_vertical"
android:id="@+id/picture_actionbar"
android:id="@+id/toolbar_title"
android:maxLines="1"
android:textColor="?attr/actionBarTextColor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp" />
</LinearLayout>
<ImageView
android:id="@+id/action_save"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="end"
android:src="@drawable/ic_save_white"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:gravity="center_vertical"
tools:ignore="ContentDescription" />
</android.support.v7.widget.Toolbar>

View File

@ -26,4 +26,9 @@
android:title="@string/more_action_2"
android:icon="@drawable/ic_block"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_mention"
android:title="@string/more_action_7"
android:icon="@drawable/ic_chat_bubble_outline"
app:showAsAction="ifRoom" />
</menu>

View File

@ -256,9 +256,9 @@
<string name="toast_report">Le pouet a été signalé !</string>
<string name="toast_unstatus">Le pouet a été supprimé !</string>
<string name="toast_error">Oups ! Une erreur s\'est produite !</string>
<string name="toast_code_error">Une erreur s\'est produite ! L\'instance n\'a retourné aucun code d\authorisation !</string>
<string name="toast_code_error">Une erreur s\'est produite ! L\'instance n\'a retourné aucun code d\autorisation !</string>
<string name="toast_error_instance">Le nom de l\'instance ne semble pas être valide !</string>
<string name="toast_error_loading_account">Une erreur s\'est produite en chargeant le compte !</string>
<string name="toast_error_loading_account">Une erreur s\'est produite pendant le chargement du compte !</string>
<string name="toast_error_search">Une erreur s\'est produite lors de la recherche !</string>
<string name="toast_error_login">Impossible de vous connecter !</string>
<string name="toast_update_credential_ok">Les données du profil ont été sauvegardées !</string>
@ -438,4 +438,4 @@
<string name="disclaimer_full">Les données ci-dessous peuvent ne pas refléter ce profil dans sa totalité.</string>
<string name="insert_emoji">Insérer un émoji</string>
<string name="no_emoji">L\'application n\'a pas encore collecté d\'emojis personnalisés</string>
</resources>
</resources>