fixes db migration issue + some other minor bugs + prepares release 1.3.5
This commit is contained in:
parent
8c69adfe9a
commit
b5063e3eb9
93
README.md
93
README.md
|
@ -1,59 +1,64 @@
|
||||||
<b>Mastalab is a multi-accounts client for Mastodon</b>
|
## Mastalab is a multi-accounts client for Mastodon
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
**Features**
|
### Features
|
||||||
|
|
||||||
<b>Multi-accounts management</b>
|
**Multi-accounts management**
|
||||||
- Add accounts from different instances
|
* Add accounts from different instances
|
||||||
- Switch from one account to another by a simple click
|
* Switch from one account to another by a simple click
|
||||||
|
|
||||||
<b>Timelines</b>
|
**Timelines**
|
||||||
- Federated / Local / Home
|
* Federated / Local / Home
|
||||||
- Switch from one timeline to another by using the menu or by swiping the screen.
|
* Switch from one timeline to another by using the menu or by swiping the screen.
|
||||||
- Clicks on toots display the related conversations (context)
|
* Clicks on toots display the related conversations (context)
|
||||||
- Clicks on mentioned accounts display details about these accounts
|
* Clicks on mentioned accounts display details about these accounts
|
||||||
- Clicks on hashtags display toots containing this hashtags
|
* Clicks on hashtags display toots containing this hashtags
|
||||||
|
|
||||||
<b>Actions on toots</b>
|
**Actions on toots**
|
||||||
- Mute an account related to a toot
|
* Mute an account related to a toot
|
||||||
- Block an account related to a toot
|
* Block an account related to a toot
|
||||||
- Report inappropriate toots to administrators
|
* Report inappropriate toots to administrators
|
||||||
- Add/Remove a toot from favourites
|
* Add/Remove a toot from favourites
|
||||||
- Boost/Unboost toots
|
* Boost/Unboost toots
|
||||||
- Copy the content of a toot
|
* Copy the content of a toot
|
||||||
- Download media
|
* Download media
|
||||||
- Translation of toots by a simple click (via the Yandex API)
|
* Translation of toots by a simple click (via the Yandex API)
|
||||||
|
|
||||||
<b>Write a toot</b>
|
**Write a toot**
|
||||||
- Add media
|
* Add media
|
||||||
- Change the visibility of the toot
|
* Change the visibility of the toot
|
||||||
- Mention accounts in toots with autocompletion (@ + 2 characters)
|
* Mention accounts in toots with autocompletion (@ + 2 characters)
|
||||||
- Mark the content as sensitive
|
* Mark the content as sensitive
|
||||||
- Add spoilers
|
* Add spoilers
|
||||||
|
* Toots which have not been sent are saved (drafts) - can be disabled in settings
|
||||||
|
* Drafts can be edited/deleted/scheduled
|
||||||
|
|
||||||
<b>Interaction with accounts</b>
|
**Scheduled toots**
|
||||||
- Follow/Unfollow/Block/Unblock/Mute/Unmute
|
* Can be edited/deleted/scheduled at another date as long as they have not been sent.
|
||||||
- Display details of accounts
|
|
||||||
- Authorize/Reject follow requests (for locked accounts)
|
|
||||||
|
|
||||||
<b>Searches</b>
|
**Interaction with accounts**
|
||||||
- A top bar allows to make researches for accounts/tags/toots
|
* Follow/Unfollow/Block/Unblock/Mute/Unmute
|
||||||
- A click on a tag displays toots containing this tag
|
* Display details of accounts
|
||||||
|
* Authorize/Reject follow requests (for locked accounts)
|
||||||
|
|
||||||
<b>Network optimization</b>
|
**Searches**
|
||||||
- Load of media: Automatic/WIFI only/Ask
|
* A top bar allows to make researches for accounts/tags/toots
|
||||||
- Customization of the number of toots/accounts per load
|
* A click on a tag displays toots containing this tag
|
||||||
|
|
||||||
<b>Notifications</b>
|
**Network optimization**
|
||||||
- Notifications for new toots on the home page (could be disabled in settings)
|
* Load of media: Automatic/WIFI only/Ask
|
||||||
- Notifications for new events (could be disabled or filtered in settings)
|
* Customization of the number of toots/accounts per load
|
||||||
|
|
||||||
<b>Built-in browser</b>
|
**Notifications**
|
||||||
- Full screen videos
|
* Notifications for new toots on the home page (could be disabled in settings)
|
||||||
- Disable JavaScript (default: enabled)
|
* Notifications for new events (could be disabled or filtered in settings)
|
||||||
- Disable third-party cookies (default: disabled)
|
|
||||||
- Disable the built-in browser in settings
|
**Built-in browser**
|
||||||
|
* Full screen videos
|
||||||
|
* Disable JavaScript (default: enabled)
|
||||||
|
* Disable third-party cookies (default: disabled)
|
||||||
|
* Disable the built-in browser in settings
|
||||||
|
|
||||||
|
|
||||||
Developer: [@tschneider](https://mastodon.etalab.gouv.fr/@tschneider)
|
Developer: [@tschneider](https://mastodon.etalab.gouv.fr/@tschneider)
|
||||||
|
|
|
@ -7,8 +7,8 @@ android {
|
||||||
applicationId "fr.gouv.etalab.mastodon"
|
applicationId "fr.gouv.etalab.mastodon"
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 31
|
versionCode 32
|
||||||
versionName "1.3.4"
|
versionName "1.3.5"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
|
Binary file not shown.
|
@ -91,7 +91,8 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
||||||
private BroadcastReceiver hide_header;
|
private BroadcastReceiver hide_header;
|
||||||
private TextView account_note;
|
private TextView account_note;
|
||||||
private String userId;
|
private String userId;
|
||||||
private static boolean isHiddingShowing = false;
|
private boolean isHiddingShowing = false;
|
||||||
|
private static int instanceValue = 0;
|
||||||
|
|
||||||
public enum action{
|
public enum action{
|
||||||
FOLLOW,
|
FOLLOW,
|
||||||
|
@ -113,7 +114,7 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
||||||
setTheme(R.style.AppThemeDark);
|
setTheme(R.style.AppThemeDark);
|
||||||
}
|
}
|
||||||
setContentView(R.layout.activity_show_account);
|
setContentView(R.layout.activity_show_account);
|
||||||
|
instanceValue += 1;
|
||||||
imageLoader = ImageLoader.getInstance();
|
imageLoader = ImageLoader.getInstance();
|
||||||
statuses = new ArrayList<>();
|
statuses = new ArrayList<>();
|
||||||
boolean isOnWifi = Helper.isOnWIFI(getApplicationContext());
|
boolean isOnWifi = Helper.isOnWIFI(getApplicationContext());
|
||||||
|
@ -220,12 +221,12 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
||||||
public void run() {
|
public void run() {
|
||||||
isHiddingShowing = false;
|
isHiddingShowing = false;
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(hide_header, new IntentFilter(Helper.HEADER_ACCOUNT));
|
LocalBroadcastManager.getInstance(this).registerReceiver(hide_header, new IntentFilter(Helper.HEADER_ACCOUNT+String.valueOf(instanceValue)));
|
||||||
|
|
||||||
//Follow button
|
//Follow button
|
||||||
account_follow.setOnClickListener(new View.OnClickListener() {
|
account_follow.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@ -380,6 +381,7 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
||||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.USER);
|
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.USER);
|
||||||
bundle.putString("targetedId", accountId);
|
bundle.putString("targetedId", accountId);
|
||||||
bundle.putBoolean("hideHeader",true);
|
bundle.putBoolean("hideHeader",true);
|
||||||
|
bundle.putString("hideHeaderValue",String.valueOf(instanceValue));
|
||||||
displayStatusFragment.setArguments(bundle);
|
displayStatusFragment.setArguments(bundle);
|
||||||
return displayStatusFragment;
|
return displayStatusFragment;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -387,6 +389,7 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
||||||
bundle.putSerializable("type", RetrieveAccountsAsyncTask.Type.FOLLOWING);
|
bundle.putSerializable("type", RetrieveAccountsAsyncTask.Type.FOLLOWING);
|
||||||
bundle.putString("targetedId", accountId);
|
bundle.putString("targetedId", accountId);
|
||||||
bundle.putBoolean("hideHeader",true);
|
bundle.putBoolean("hideHeader",true);
|
||||||
|
bundle.putString("hideHeaderValue",String.valueOf(instanceValue));
|
||||||
displayAccountsFragment.setArguments(bundle);
|
displayAccountsFragment.setArguments(bundle);
|
||||||
return displayAccountsFragment;
|
return displayAccountsFragment;
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -394,6 +397,7 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
||||||
bundle.putSerializable("type", RetrieveAccountsAsyncTask.Type.FOLLOWERS);
|
bundle.putSerializable("type", RetrieveAccountsAsyncTask.Type.FOLLOWERS);
|
||||||
bundle.putString("targetedId", accountId);
|
bundle.putString("targetedId", accountId);
|
||||||
bundle.putBoolean("hideHeader",true);
|
bundle.putBoolean("hideHeader",true);
|
||||||
|
bundle.putString("hideHeaderValue",String.valueOf(instanceValue));
|
||||||
displayAccountsFragment.setArguments(bundle);
|
displayAccountsFragment.setArguments(bundle);
|
||||||
return displayAccountsFragment;
|
return displayAccountsFragment;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,13 @@ package fr.gouv.etalab.mastodon.drawers;
|
||||||
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||||
* see <http://www.gnu.org/licenses>. */
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
@ -30,16 +33,22 @@ import android.widget.BaseAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
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;
|
||||||
import fr.gouv.etalab.mastodon.activities.TootActivity;
|
import fr.gouv.etalab.mastodon.activities.TootActivity;
|
||||||
|
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
|
||||||
|
import fr.gouv.etalab.mastodon.client.API;
|
||||||
|
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||||
|
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||||
|
@ -52,19 +61,23 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
||||||
* Created by Thomas on 24/04/2017.
|
* Created by Thomas on 24/04/2017.
|
||||||
* Adapter for Status
|
* Adapter for Status
|
||||||
*/
|
*/
|
||||||
public class NotificationsListAdapter extends BaseAdapter {
|
public class NotificationsListAdapter extends BaseAdapter implements OnPostActionInterface {
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private List<Notification> notifications;
|
private List<Notification> notifications;
|
||||||
private LayoutInflater layoutInflater;
|
private LayoutInflater layoutInflater;
|
||||||
private ImageLoader imageLoader;
|
private ImageLoader imageLoader;
|
||||||
private DisplayImageOptions options;
|
private DisplayImageOptions options;
|
||||||
|
private final int REBLOG = 1;
|
||||||
|
private final int FAVOURITE = 2;
|
||||||
|
private NotificationsListAdapter notificationsListAdapter;
|
||||||
|
|
||||||
public NotificationsListAdapter(Context context, List<Notification> notifications){
|
public NotificationsListAdapter(Context context, List<Notification> notifications){
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.notifications = notifications;
|
this.notifications = notifications;
|
||||||
layoutInflater = LayoutInflater.from(this.context);
|
layoutInflater = LayoutInflater.from(this.context);
|
||||||
imageLoader = ImageLoader.getInstance();
|
imageLoader = ImageLoader.getInstance();
|
||||||
|
notificationsListAdapter = this;
|
||||||
options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||||
}
|
}
|
||||||
|
@ -130,7 +143,7 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
}
|
}
|
||||||
holder.notification_type.setText(typeString);
|
holder.notification_type.setText(typeString);
|
||||||
|
|
||||||
|
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
|
||||||
final Status status = notification.getStatus();
|
final Status status = notification.getStatus();
|
||||||
if( status != null ){
|
if( status != null ){
|
||||||
|
@ -138,7 +151,6 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
holder.status_document_container.setVisibility(View.GONE);
|
holder.status_document_container.setVisibility(View.GONE);
|
||||||
else
|
else
|
||||||
holder.status_document_container.setVisibility(View.VISIBLE);
|
holder.status_document_container.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
if( (status.getIn_reply_to_account_id() != null && !status.getIn_reply_to_account_id().equals("null")) || (status.getIn_reply_to_id() != null && !status.getIn_reply_to_id().equals("null")) ){
|
if( (status.getIn_reply_to_account_id() != null && !status.getIn_reply_to_account_id().equals("null")) || (status.getIn_reply_to_id() != null && !status.getIn_reply_to_id().equals("null")) ){
|
||||||
Drawable img = ContextCompat.getDrawable(context, R.drawable.ic_reply);
|
Drawable img = ContextCompat.getDrawable(context, R.drawable.ic_reply);
|
||||||
img.setBounds(0,0,(int) (20 * scale + 0.5f),(int) (15 * scale + 0.5f));
|
img.setBounds(0,0,(int) (20 * scale + 0.5f),(int) (15 * scale + 0.5f));
|
||||||
|
@ -161,7 +173,7 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
holder.status_date.setText(Helper.dateDiff(context, status.getCreated_at()));
|
holder.status_date.setText(Helper.dateDiff(context, status.getCreated_at()));
|
||||||
|
|
||||||
//Manages theme for icon colors
|
//Manages theme for icon colors
|
||||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
|
||||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||||
if( theme == Helper.THEME_DARK){
|
if( theme == Helper.THEME_DARK){
|
||||||
changeDrawableColor(context, R.drawable.ic_reply,R.color.dark_text);
|
changeDrawableColor(context, R.drawable.ic_reply,R.color.dark_text);
|
||||||
|
@ -171,6 +183,7 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.dark_text);
|
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.dark_text);
|
||||||
changeDrawableColor(context, R.drawable.ic_local_post_office,R.color.dark_text);
|
changeDrawableColor(context, R.drawable.ic_local_post_office,R.color.dark_text);
|
||||||
changeDrawableColor(context, R.drawable.ic_retweet_black,R.color.dark_text);
|
changeDrawableColor(context, R.drawable.ic_retweet_black,R.color.dark_text);
|
||||||
|
changeDrawableColor(context, R.drawable.ic_retweet,R.color.dark_text);
|
||||||
changeDrawableColor(context, R.drawable.ic_fav_black,R.color.dark_text);
|
changeDrawableColor(context, R.drawable.ic_fav_black,R.color.dark_text);
|
||||||
changeDrawableColor(context, R.drawable.ic_photo,R.color.dark_text);
|
changeDrawableColor(context, R.drawable.ic_photo,R.color.dark_text);
|
||||||
changeDrawableColor(context, R.drawable.ic_remove_red_eye,R.color.dark_text);
|
changeDrawableColor(context, R.drawable.ic_remove_red_eye,R.color.dark_text);
|
||||||
|
@ -182,6 +195,7 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.black);
|
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.black);
|
||||||
changeDrawableColor(context, R.drawable.ic_local_post_office,R.color.black);
|
changeDrawableColor(context, R.drawable.ic_local_post_office,R.color.black);
|
||||||
changeDrawableColor(context, R.drawable.ic_retweet_black,R.color.black);
|
changeDrawableColor(context, R.drawable.ic_retweet_black,R.color.black);
|
||||||
|
changeDrawableColor(context, R.drawable.ic_retweet,R.color.black);
|
||||||
changeDrawableColor(context, R.drawable.ic_fav_black,R.color.black);
|
changeDrawableColor(context, R.drawable.ic_fav_black,R.color.black);
|
||||||
changeDrawableColor(context, R.drawable.ic_photo,R.color.black);
|
changeDrawableColor(context, R.drawable.ic_photo,R.color.black);
|
||||||
changeDrawableColor(context, R.drawable.ic_remove_red_eye,R.color.black);
|
changeDrawableColor(context, R.drawable.ic_remove_red_eye,R.color.black);
|
||||||
|
@ -214,6 +228,18 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
holder.status_privacy.setImageResource(R.drawable.ic_local_post_office);
|
holder.status_privacy.setImageResource(R.drawable.ic_local_post_office);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
switch (status.getVisibility()){
|
||||||
|
case "direct":
|
||||||
|
case "private":
|
||||||
|
holder.status_reblog_count.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
case "public":
|
||||||
|
case "unlisted":
|
||||||
|
holder.status_reblog_count.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
holder.status_reblog_count.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
Drawable imgFav, imgReblog;
|
Drawable imgFav, imgReblog;
|
||||||
if( status.isFavourited())
|
if( status.isFavourited())
|
||||||
imgFav = ContextCompat.getDrawable(context, R.drawable.ic_fav_yellow);
|
imgFav = ContextCompat.getDrawable(context, R.drawable.ic_fav_yellow);
|
||||||
|
@ -234,6 +260,28 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
holder.status_favorite_count.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
boolean confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true);
|
||||||
|
if( confirmation )
|
||||||
|
displayConfirmationDialog(FAVOURITE,status);
|
||||||
|
else
|
||||||
|
favouriteAction(status);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
holder.status_reblog_count.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
boolean confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true);
|
||||||
|
if( confirmation )
|
||||||
|
displayConfirmationDialog(REBLOG,status);
|
||||||
|
else
|
||||||
|
reblogAction(status);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
holder.notification_account_profile.setOnClickListener(new View.OnClickListener() {
|
holder.notification_account_profile.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -245,6 +293,7 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
holder.status_reply.setOnClickListener(new View.OnClickListener() {
|
holder.status_reply.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
@ -256,6 +305,7 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
holder.notification_account_displayname.setText(Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true));
|
holder.notification_account_displayname.setText(Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true));
|
||||||
holder.notification_account_username.setText( String.format("@%s",notification.getAccount().getUsername()));
|
holder.notification_account_username.setText( String.format("@%s",notification.getAccount().getUsername()));
|
||||||
//Profile picture
|
//Profile picture
|
||||||
|
@ -263,6 +313,94 @@ public class NotificationsListAdapter extends BaseAdapter {
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a validation message
|
||||||
|
* @param action int
|
||||||
|
* @param status Status
|
||||||
|
*/
|
||||||
|
private void displayConfirmationDialog(final int action, final Status status){
|
||||||
|
|
||||||
|
String title = null;
|
||||||
|
if( action == FAVOURITE){
|
||||||
|
if( status.isFavourited())
|
||||||
|
title = context.getString(R.string.favourite_remove);
|
||||||
|
else
|
||||||
|
title = context.getString(R.string.favourite_add);
|
||||||
|
}else if( action == REBLOG ){
|
||||||
|
if( status.isReblogged())
|
||||||
|
title = context.getString(R.string.reblog_remove);
|
||||||
|
else
|
||||||
|
title = context.getString(R.string.reblog_add);
|
||||||
|
}
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
|
builder.setMessage(Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_COMPACT));
|
||||||
|
else
|
||||||
|
//noinspection deprecation
|
||||||
|
builder.setMessage(Html.fromHtml(status.getContent()));
|
||||||
|
builder.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
|
.setTitle(title)
|
||||||
|
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if( action == REBLOG)
|
||||||
|
reblogAction(status);
|
||||||
|
else if( action == FAVOURITE)
|
||||||
|
favouriteAction(status);
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favourites/Unfavourites a status
|
||||||
|
* @param status Status
|
||||||
|
*/
|
||||||
|
private void favouriteAction(Status status){
|
||||||
|
if( status.isFavourited()){
|
||||||
|
new PostActionAsyncTask(context, API.StatusAction.UNFAVOURITE, status.getId(), NotificationsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
status.setFavourited(false);
|
||||||
|
}else{
|
||||||
|
new PostActionAsyncTask(context, API.StatusAction.FAVOURITE, status.getId(), NotificationsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
status.setFavourited(true);
|
||||||
|
}
|
||||||
|
notificationsListAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reblog/Unreblog a status
|
||||||
|
* @param status Status
|
||||||
|
*/
|
||||||
|
private void reblogAction(Status status){
|
||||||
|
if( status.isReblogged()){
|
||||||
|
new PostActionAsyncTask(context, API.StatusAction.UNREBLOG, status.getId(), NotificationsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
status.setReblogged(false);
|
||||||
|
}else{
|
||||||
|
new PostActionAsyncTask(context, API.StatusAction.REBLOG, status.getId(), NotificationsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
status.setReblogged(true);
|
||||||
|
}
|
||||||
|
notificationsListAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
||||||
|
if( error != null){
|
||||||
|
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
|
||||||
|
if( show_error_messages)
|
||||||
|
Toast.makeText(context, error.getError(),Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class ViewHolder {
|
private class ViewHolder {
|
||||||
TextView notification_status_content;
|
TextView notification_status_content;
|
||||||
|
|
|
@ -478,9 +478,21 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
||||||
if( confirmation )
|
if( confirmation )
|
||||||
displayConfirmationDialog(REBLOG,status);
|
displayConfirmationDialog(REBLOG,status);
|
||||||
else
|
else
|
||||||
favouriteAction(status);
|
reblogAction(status);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
switch (status.getVisibility()){
|
||||||
|
case "direct":
|
||||||
|
case "private":
|
||||||
|
holder.status_reblog_count.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
case "public":
|
||||||
|
case "unlisted":
|
||||||
|
holder.status_reblog_count.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
holder.status_reblog_count.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
holder.status_more.setOnClickListener(new View.OnClickListener() {
|
holder.status_more.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.os.Parcelable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -61,7 +62,7 @@ public class DisplayAccountsFragment extends Fragment implements OnRetrieveAccou
|
||||||
private String targetedId;
|
private String targetedId;
|
||||||
private boolean swiped;
|
private boolean swiped;
|
||||||
private ListView lv_accounts;
|
private ListView lv_accounts;
|
||||||
|
private String instanceValue;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
@ -77,6 +78,7 @@ public class DisplayAccountsFragment extends Fragment implements OnRetrieveAccou
|
||||||
type = (RetrieveAccountsAsyncTask.Type) bundle.get("type");
|
type = (RetrieveAccountsAsyncTask.Type) bundle.get("type");
|
||||||
targetedId = bundle.getString("targetedId", null);
|
targetedId = bundle.getString("targetedId", null);
|
||||||
hideHeader = bundle.getBoolean("hideHeader", false);
|
hideHeader = bundle.getBoolean("hideHeader", false);
|
||||||
|
instanceValue = bundle.getString("hideHeaderValue", null);
|
||||||
if( bundle.containsKey("accounts")){
|
if( bundle.containsKey("accounts")){
|
||||||
ArrayList<Parcelable> accountsReceived = bundle.getParcelableArrayList("accounts");
|
ArrayList<Parcelable> accountsReceived = bundle.getParcelableArrayList("accounts");
|
||||||
assert accountsReceived != null;
|
assert accountsReceived != null;
|
||||||
|
@ -117,19 +119,15 @@ public class DisplayAccountsFragment extends Fragment implements OnRetrieveAccou
|
||||||
@Override
|
@Override
|
||||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||||
|
|
||||||
if( firstVisibleItem == 0) {
|
if (view.getId() == lv_accounts.getId() && totalItemCount > visibleItemCount) {
|
||||||
Intent intent = new Intent(Helper.HEADER_ACCOUNT);
|
|
||||||
intent.putExtra("hide", false);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
}else if (view.getId() == lv_accounts.getId() && totalItemCount > visibleItemCount) {
|
|
||||||
final int currentFirstVisibleItem = lv_accounts.getFirstVisiblePosition();
|
final int currentFirstVisibleItem = lv_accounts.getFirstVisiblePosition();
|
||||||
|
|
||||||
if (currentFirstVisibleItem > lastFirstVisibleItem) {
|
if (currentFirstVisibleItem > lastFirstVisibleItem) {
|
||||||
Intent intent = new Intent(Helper.HEADER_ACCOUNT);
|
Intent intent = new Intent(Helper.HEADER_ACCOUNT + instanceValue);
|
||||||
intent.putExtra("hide", true);
|
intent.putExtra("hide", true);
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||||
} else if (currentFirstVisibleItem < lastFirstVisibleItem) {
|
} else if (currentFirstVisibleItem < lastFirstVisibleItem) {
|
||||||
Intent intent = new Intent(Helper.HEADER_ACCOUNT);
|
Intent intent = new Intent(Helper.HEADER_ACCOUNT + instanceValue);
|
||||||
intent.putExtra("hide", false);
|
intent.putExtra("hide", false);
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
||||||
private ListView lv_status;
|
private ListView lv_status;
|
||||||
private boolean isOnWifi;
|
private boolean isOnWifi;
|
||||||
private int behaviorWithAttachments;
|
private int behaviorWithAttachments;
|
||||||
|
private String instanceValue;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
@ -84,6 +85,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
||||||
targetedId = bundle.getString("targetedId", null);
|
targetedId = bundle.getString("targetedId", null);
|
||||||
tag = bundle.getString("tag", null);
|
tag = bundle.getString("tag", null);
|
||||||
hideHeader = bundle.getBoolean("hideHeader", false);
|
hideHeader = bundle.getBoolean("hideHeader", false);
|
||||||
|
instanceValue = bundle.getString("hideHeaderValue", null);
|
||||||
if( bundle.containsKey("statuses")){
|
if( bundle.containsKey("statuses")){
|
||||||
ArrayList<Parcelable> statusesReceived = bundle.getParcelableArrayList("statuses");
|
ArrayList<Parcelable> statusesReceived = bundle.getParcelableArrayList("statuses");
|
||||||
assert statusesReceived != null;
|
assert statusesReceived != null;
|
||||||
|
@ -126,19 +128,15 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||||
if( firstVisibleItem == 0) {
|
if (view.getId() == lv_status.getId() && totalItemCount > visibleItemCount) {
|
||||||
Intent intent = new Intent(Helper.HEADER_ACCOUNT);
|
|
||||||
intent.putExtra("hide", false);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
}else if (view.getId() == lv_status.getId() && totalItemCount > visibleItemCount) {
|
|
||||||
final int currentFirstVisibleItem = lv_status.getFirstVisiblePosition();
|
final int currentFirstVisibleItem = lv_status.getFirstVisiblePosition();
|
||||||
|
|
||||||
if (currentFirstVisibleItem > lastFirstVisibleItem) {
|
if (currentFirstVisibleItem > lastFirstVisibleItem) {
|
||||||
Intent intent = new Intent(Helper.HEADER_ACCOUNT);
|
Intent intent = new Intent(Helper.HEADER_ACCOUNT+instanceValue);
|
||||||
intent.putExtra("hide", true);
|
intent.putExtra("hide", true);
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||||
} else if (currentFirstVisibleItem < lastFirstVisibleItem) {
|
} else if (currentFirstVisibleItem < lastFirstVisibleItem) {
|
||||||
Intent intent = new Intent(Helper.HEADER_ACCOUNT);
|
Intent intent = new Intent(Helper.HEADER_ACCOUNT+instanceValue);
|
||||||
intent.putExtra("hide", false);
|
intent.putExtra("hide", false);
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
private static final String CREATE_TABLE_STATUSES_STORED = "CREATE TABLE " + TABLE_STATUSES_STORED + " ("
|
private static final String CREATE_TABLE_STATUSES_STORED = "CREATE TABLE " + TABLE_STATUSES_STORED + " ("
|
||||||
+ COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
+ COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
+ COL_USER_ID + " TEXT NOT NULL, " + COL_INSTANCE + " TEXT NOT NULL, "
|
+ COL_USER_ID + " TEXT NOT NULL, " + COL_INSTANCE + " TEXT NOT NULL, "
|
||||||
+ COL_STATUS_SERIALIZED + " TEXT NOT NULL, " + COL_DATE_CREATION + " TEXT NOT NULL, "
|
+ COL_STATUS_SERIALIZED + " TEXT NOT NULL, " + COL_STATUS_REPLY_SERIALIZED + " TEXT, " + COL_DATE_CREATION + " TEXT NOT NULL, "
|
||||||
+ COL_IS_SCHEDULED + " INTEGER NOT NULL, " + COL_DATE_SCHEDULED + " TEXT, "
|
+ COL_IS_SCHEDULED + " INTEGER NOT NULL, " + COL_DATE_SCHEDULED + " TEXT, "
|
||||||
+ COL_SENT + " INTEGER NOT NULL, " + COL_DATE_SENT + " TEXT)";
|
+ COL_SENT + " INTEGER NOT NULL, " + COL_DATE_SENT + " TEXT)";
|
||||||
|
|
||||||
|
@ -112,7 +112,8 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
case 1:
|
case 1:
|
||||||
db.execSQL(CREATE_TABLE_STATUSES_STORED);
|
db.execSQL(CREATE_TABLE_STATUSES_STORED);
|
||||||
case 2:
|
case 2:
|
||||||
db.execSQL("ALTER TABLE " + TABLE_STATUSES_STORED + " ADD COLUMN " + COL_STATUS_REPLY_SERIALIZED + " TEXT");
|
db.execSQL("DROP TABLE IF EXISTS " + TABLE_STATUSES_STORED);
|
||||||
|
db.execSQL(CREATE_TABLE_STATUSES_STORED);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue