Merged in BadgeView (pull request #80)

BadgeView
This commit is contained in:
tom79 2017-08-25 13:31:31 +00:00
commit 529a6d79f0
26 changed files with 669 additions and 145 deletions

View File

@ -158,7 +158,7 @@ public class HashTagActivity extends AppCompatActivity implements OnRetrieveFeed
}
@Override
public void onRetrieveFeeds(APIResponse apiResponse) {
public void onRetrieveFeeds(APIResponse apiResponse, boolean refreshData) {
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);

View File

@ -14,22 +14,20 @@
* see <http://www.gnu.org/licenses>. */
package fr.gouv.etalab.mastodon.activities;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
@ -48,6 +46,7 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
@ -64,9 +63,11 @@ import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoByIDAsyncTask;
import fr.gouv.etalab.mastodon.client.Entities.Account;
@ -91,6 +92,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
import static fr.gouv.etalab.mastodon.helper.Helper.NOTIFICATION_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID;
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_DARK;
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
import static fr.gouv.etalab.mastodon.helper.Helper.changeUser;
import static fr.gouv.etalab.mastodon.helper.Helper.loadPPInActionBar;
@ -117,7 +119,8 @@ public class MainActivity extends AppCompatActivity
private ViewPager viewPager;
private RelativeLayout main_app_container;
private Stack<Integer> stackBack = new Stack<>();
private DisplayStatusFragment homeFragment;
private DisplayNotificationsFragment notificationsFragment;
public MainActivity() {
@ -154,12 +157,52 @@ public class MainActivity extends AppCompatActivity
pp_actionBar = (ImageView) toolbar.findViewById(R.id.pp_actionBar);
toolbar_search = (SearchView) toolbar.findViewById(R.id.toolbar_search);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
TabLayout.Tab tabHome = tabLayout.newTab();
TabLayout.Tab tabNotif = tabLayout.newTab();
TabLayout.Tab tabLocal = tabLayout.newTab();
TabLayout.Tab tabPublic = tabLayout.newTab();
tabHome.setCustomView(R.layout.tab_badge);
tabNotif.setCustomView(R.layout.tab_badge);
tabLocal.setCustomView(R.layout.tab_badge);
tabPublic.setCustomView(R.layout.tab_badge);
@SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId")
ImageView iconHome = (ImageView) tabHome.getCustomView().findViewById(R.id.tab_icon);
iconHome.setImageResource(R.drawable.ic_action_home_tl);
@SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId")
ImageView iconNotif = (ImageView) tabNotif.getCustomView().findViewById(R.id.tab_icon);
iconNotif.setImageResource(R.drawable.ic_notifications_tl);
@SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId")
ImageView iconLocal = (ImageView) tabLocal.getCustomView().findViewById(R.id.tab_icon);
iconLocal.setImageResource(R.drawable.ic_action_users_tl);
@SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId")
ImageView iconGlobal = (ImageView) tabPublic.getCustomView().findViewById(R.id.tab_icon);
iconGlobal.setImageResource(R.drawable.ic_action_globe_tl);
changeDrawableColor(getApplicationContext(), R.drawable.ic_action_home_tl,R.color.dark_text);
changeDrawableColor(getApplicationContext(), R.drawable.ic_notifications_tl,R.color.dark_text);
changeDrawableColor(getApplicationContext(), R.drawable.ic_action_users_tl,R.color.dark_text);
changeDrawableColor(getApplicationContext(), R.drawable.ic_action_globe_tl,R.color.dark_text);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.addTab(tabHome);
tabLayout.addTab(tabNotif);
tabLayout.addTab(tabLocal);
tabLayout.addTab(tabPublic);
viewPager = (ViewPager) findViewById(R.id.viewpager);
main_app_container = (RelativeLayout) findViewById(R.id.main_app_container);
PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
final boolean bubbles = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
@ -182,10 +225,16 @@ public class MainActivity extends AppCompatActivity
case 0:
item = navigationView.getMenu().findItem(R.id.nav_home);
fragmentTag = "HOME_TIMELINE";
if( bubbles && homeFragment != null)
homeFragment.refreshData();
updateHomeCounter(0);
break;
case 1:
fragmentTag = "NOTIFICATIONS";
item = navigationView.getMenu().findItem(R.id.nav_notification);
updateNotifCounter(0);
if( bubbles && notificationsFragment != null)
notificationsFragment.refreshData();
break;
case 2:
fragmentTag = "LOCAL_TIMELINE";
@ -753,6 +802,15 @@ public class MainActivity extends AppCompatActivity
@Override
public void onResume(){
super.onResume();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean bubbles = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
if( bubbles){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {refreshData();}
}, 1000);
}
//Proceeds to update of the authenticated account
if(Helper.isLoggedIn(getApplicationContext()))
new UpdateAccountInfoByIDAsyncTask(getApplicationContext(), MainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -917,12 +975,13 @@ public class MainActivity extends AppCompatActivity
Bundle bundle = new Bundle();
switch (position) {
case 0:
statusFragment = new DisplayStatusFragment();
homeFragment = new DisplayStatusFragment();
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.HOME);
statusFragment.setArguments(bundle);
return statusFragment;
homeFragment.setArguments(bundle);
return homeFragment;
case 1:
return new DisplayNotificationsFragment();
notificationsFragment = new DisplayNotificationsFragment();
return notificationsFragment;
case 2:
statusFragment = new DisplayStatusFragment();
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.LOCAL);
@ -943,4 +1002,70 @@ public class MainActivity extends AppCompatActivity
}
}
private void refreshData(){
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
String prefKeyOauthTokenT = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Account account = new AccountDAO(getApplicationContext(), db).getAccountByToken(prefKeyOauthTokenT);
if( account != null){
String last_refresh = sharedpreferences.getString(Helper.LAST_BUBBLE_REFRESH_NOTIF + account.getId(), null);
Date last_refresh_date = Helper.stringToDate(getApplicationContext(), last_refresh);
if (last_refresh_date == null || (new Date().getTime() - last_refresh_date.getTime()) >= TimeUnit.SECONDS.toMillis(5)) {
if( notificationsFragment != null ){
notificationsFragment.update();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_BUBBLE_REFRESH_NOTIF+ account.getId(),Helper.dateToString(getApplicationContext(), new Date()));
editor.apply();
}
}
last_refresh = sharedpreferences.getString(Helper.LAST_BUBBLE_REFRESH_HOME + account.getId(), null);
last_refresh_date = Helper.stringToDate(getApplicationContext(), last_refresh);
if (last_refresh_date == null || (new Date().getTime() - last_refresh_date.getTime()) >= TimeUnit.SECONDS.toMillis(5)) {
if( homeFragment != null ){
homeFragment.update();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_BUBBLE_REFRESH_HOME+ account.getId(),Helper.dateToString(getApplicationContext(), new Date()));
editor.apply();
}
}
}
}
public void updateHomeCounter(int newHomeCount){
if( tabLayout.getTabAt(0) == null )
return;
View tabHome = tabLayout.getTabAt(0).getCustomView();
TextView tabCounterHome = (TextView) tabHome.findViewById(R.id.tab_counter);
tabCounterHome.setText(String.valueOf(newHomeCount));
if( newHomeCount > 0){
//New data are available
//The fragment is not displayed, so the counter is displayed
if( tabLayout.getSelectedTabPosition() != 0)
tabCounterHome.setVisibility(View.VISIBLE);
else
tabCounterHome.setVisibility(View.GONE);
}else {
tabCounterHome.setVisibility(View.GONE);
}
}
public void updateNotifCounter(int newNotifCount){
if(tabLayout.getTabAt(1) == null)
return;
View tabNotif = tabLayout.getTabAt(1).getCustomView();
TextView tabCounterNotif = (TextView) tabNotif.findViewById(R.id.tab_counter);
tabCounterNotif.setText(String.valueOf(newNotifCount));
if( newNotifCount > 0){
if( tabLayout.getSelectedTabPosition() != 1)
tabCounterNotif.setVisibility(View.VISIBLE);
else
tabCounterNotif.setVisibility(View.GONE);
}else {
tabCounterNotif.setVisibility(View.GONE);
}
}
}

View File

@ -216,7 +216,7 @@ public class ShowConversationActivity extends AppCompatActivity implements OnRet
}
@Override
public void onRetrieveFeeds(APIResponse apiResponse) {
public void onRetrieveFeeds(APIResponse apiResponse, boolean refreshData) {
if( apiResponse.getError() != null){
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);

View File

@ -15,9 +15,14 @@
package fr.gouv.etalab.mastodon.asynctasks;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import java.util.Date;
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface;
@ -36,6 +41,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
private String targetedID;
private String tag;
private boolean showMediaOnly = false;
private boolean refreshData;
public enum Type{
HOME,
@ -54,6 +60,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
this.action = action;
this.max_id = max_id;
this.listener = onRetrieveFeedsInterface;
this.refreshData = true;
updateTimeRefresh();
}
public RetrieveFeedsAsyncTask(Context context, Type action, String targetedID, String max_id, boolean showMediaOnly, OnRetrieveFeedsInterface onRetrieveFeedsInterface){
@ -63,6 +72,8 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
this.listener = onRetrieveFeedsInterface;
this.targetedID = targetedID;
this.showMediaOnly = showMediaOnly;
this.refreshData = true;
updateTimeRefresh();
}
public RetrieveFeedsAsyncTask(Context context, Type action, String tag, String targetedID, String max_id, OnRetrieveFeedsInterface onRetrieveFeedsInterface){
this.context = context;
@ -71,7 +82,19 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
this.listener = onRetrieveFeedsInterface;
this.targetedID = targetedID;
this.tag = tag;
this.refreshData = true;
updateTimeRefresh();
}
public RetrieveFeedsAsyncTask(Context context, Type action, String max_id, boolean refreshData, OnRetrieveFeedsInterface onRetrieveFeedsInterface){
this.context = context;
this.action = action;
this.max_id = max_id;
this.listener = onRetrieveFeedsInterface;
this.refreshData = refreshData;
updateTimeRefresh();
}
@Override
protected Void doInBackground(Void... params) {
@ -109,7 +132,16 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void result) {
listener.onRetrieveFeeds(apiResponse);
listener.onRetrieveFeeds(apiResponse, refreshData);
}
private void updateTimeRefresh(){
if( action == Type.HOME) {
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_BUBBLE_REFRESH_HOME + userId, Helper.dateToString(context, new Date()));
editor.apply();
}
}
}

View File

@ -15,9 +15,14 @@
package fr.gouv.etalab.mastodon.asynctasks;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import java.util.Date;
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveNotificationsInterface;
@ -35,7 +40,7 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask<Void, Void, Void>
private OnRetrieveNotificationsInterface listener;
private String instance;
private String token;
private boolean refreshData;
public RetrieveNotificationsAsyncTask(Context context, String instance, String token, String max_id, String acct, String userId, OnRetrieveNotificationsInterface onRetrieveNotificationsInterface){
this.context = context;
@ -45,6 +50,20 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask<Void, Void, Void>
this.instance = instance;
this.userId = userId;
this.token = token;
this.refreshData = true;
updateTimeRefresh();
}
public RetrieveNotificationsAsyncTask(Context context, String instance, String token, String max_id, String acct, String userId, boolean refreshData, OnRetrieveNotificationsInterface onRetrieveNotificationsInterface){
this.context = context;
this.max_id = max_id;
this.listener = onRetrieveNotificationsInterface;
this.acct = acct;
this.instance = instance;
this.userId = userId;
this.token = token;
this.refreshData = refreshData;
updateTimeRefresh();
}
@Override
@ -60,7 +79,13 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask<Void, Void, Void>
@Override
protected void onPostExecute(Void result) {
listener.onRetrieveNotifications(apiResponse, acct, userId);
listener.onRetrieveNotifications(apiResponse, acct, userId, refreshData);
}
private void updateTimeRefresh(){
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_BUBBLE_REFRESH_NOTIF+ userId,Helper.dateToString(context, new Date()));
editor.apply();
}
}

View File

@ -16,7 +16,7 @@ package fr.gouv.etalab.mastodon.client;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpResponseHandler;

View File

@ -20,17 +20,21 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import fr.gouv.etalab.mastodon.activities.MainActivity;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.drawers.NotificationsListAdapter;
@ -56,13 +60,19 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
private AsyncTask<Void, Void, Void> asyncTask;
private NotificationsListAdapter notificationsListAdapter;
private String max_id;
private List<Notification> notifications;
private List<Notification> notifications, notificationsTmp;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
private SwipeRefreshLayout swipeRefreshLayout;
private int notificationPerPage;
private boolean swiped;
private ListView lv_notifications;
private DisplayNotificationsFragment displayNotificationsFragment;
private TextView new_data;
public DisplayNotificationsFragment(){
displayNotificationsFragment = this;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -76,10 +86,9 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
swiped = false;
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipeContainer);
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
notificationPerPage = sharedpreferences.getInt(Helper.SET_NOTIFICATIONS_PER_PAGE, 15);
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
lv_notifications = (ListView) rootView.findViewById(R.id.lv_notifications);
new_data = (TextView) rootView.findViewById(R.id.new_data);
mainLoader = (RelativeLayout) rootView.findViewById(R.id.loader);
nextElementLoader = (RelativeLayout) rootView.findViewById(R.id.loading_next_notifications);
textviewNoAction = (RelativeLayout) rootView.findViewById(R.id.no_action);
@ -119,12 +128,30 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
asyncTask = new RetrieveNotificationsAsyncTask(context, null, null, max_id, null, null, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4,
R.color.mastodonC2,
R.color.mastodonC3);
asyncTask = new RetrieveNotificationsAsyncTask(context, null, null, max_id, null, null, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new_data.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if( notificationsTmp != null){
boolean isOnWifi = Helper.isOnWIFI(context);
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
notifications = new ArrayList<>();
for(Notification notification: notificationsTmp){
notifications.add(notification);
}
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
lv_notifications.setAdapter(notificationsListAdapter);
}
new_data.setVisibility(View.GONE);
notificationsTmp = new ArrayList<>();
}
});
return rootView;
}
@ -151,9 +178,9 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
}
@Override
public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId) {
public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId, boolean refreshData) {
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
@ -166,7 +193,59 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
swiped = false;
return;
}
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_BUBBLE_REFRESH_NOTIF+ userId,Helper.dateToString(context, new Date()));
editor.apply();
String bubble_max_id = sharedpreferences.getString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, null);
List<Notification> notifications = apiResponse.getNotifications();
max_id = apiResponse.getMax_id();
if( refreshData ) {
manageNotifications(notifications, max_id);
if( apiResponse.getSince_id() != null) {
editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, apiResponse.getSince_id());
editor.apply();
}
}else {
int countData = 0;
if( bubble_max_id != null) {
for (Notification nt : notifications) {
if (nt.getId().trim().equals(bubble_max_id.trim()))
break;
countData++;
}
}
if( !displayNotificationsFragment.getUserVisibleHint() ){
((MainActivity)context).updateNotifCounter(countData);
max_id = null;
firstLoad = true;
notificationsTmp = new ArrayList<>();
for(Notification tmpNotification: notifications){
this.notificationsTmp.add(tmpNotification);
}
if( apiResponse.getSince_id() != null) {
editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, apiResponse.getSince_id());
editor.apply();
}
}else {
if( notifications != null && notifications.size() > 0 && countData > 0) {
max_id = null;
firstLoad = true;
notificationsTmp = new ArrayList<>();
for(Notification tmpNotification: notifications){
this.notificationsTmp.add(tmpNotification);
}
new_data.setVisibility(View.VISIBLE);
}
}
}
}
private void manageNotifications(List<Notification> notifications, String max_id){
flag_loading = (max_id == null );
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
if( !swiped && firstLoad && (notifications == null || notifications.size() == 0))
textviewNoAction.setVisibility(View.VISIBLE);
else
@ -178,8 +257,6 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
lv_notifications.setAdapter(notificationsListAdapter);
swiped = false;
}
max_id = apiResponse.getMax_id();
if( notifications != null && notifications.size() > 0) {
for(Notification tmpNotification: notifications){
this.notifications.add(tmpNotification);
@ -187,16 +264,15 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
notificationsListAdapter.notifyDataSetChanged();
}
swipeRefreshLayout.setRefreshing(false);
flag_loading = notifications != null && notifications.size() < notificationPerPage;
//Store last notification id to avoid to notify for those that have been already seen
if( notifications != null && notifications.size() > 0) {
//acct is null as userId when used in Fragment, data need to be retrieved via shared preferences and db
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Account currentAccount = new AccountDAO(context, db).getAccountByID(userId);
if( currentAccount != null && firstLoad){
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + currentAccount.getId(), notifications.get(0).getId());
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + currentAccount.getId(), max_id);
editor.apply();
}
}
@ -207,4 +283,25 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
if( lv_notifications != null)
lv_notifications.setAdapter(notificationsListAdapter);
}
public void update(){
if( context != null){
asyncTask = new RetrieveNotificationsAsyncTask(context, null, null, null, null, null, false, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
public void refreshData(){
if(context != null && this.notificationsTmp != null && this.notificationsTmp.size() > 0){
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean isOnWifi = Helper.isOnWIFI(context);
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
notifications = new ArrayList<>();
for(Notification notification: this.notificationsTmp){
notifications.add(notification);
}
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
lv_notifications.setAdapter(notificationsListAdapter);
this.notificationsTmp = new ArrayList<>();
}
}
}

View File

@ -14,7 +14,6 @@ package fr.gouv.etalab.mastodon.fragments;
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
@ -23,16 +22,20 @@ import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import fr.gouv.etalab.mastodon.activities.MainActivity;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveRepliesAsyncTask;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Account;
@ -59,20 +62,25 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
private AsyncTask<Void, Void, Void> asyncTask;
private StatusListAdapter statusListAdapter;
private String max_id;
private List<Status> statuses;
private List<Status> statuses, statusesTmp;
private RetrieveFeedsAsyncTask.Type type;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
private SwipeRefreshLayout swipeRefreshLayout;
private String targetedId;
private String tag;
private int tootsPerPage;
private boolean swiped;
private ListView lv_status;
private boolean isOnWifi;
private int behaviorWithAttachments;
private String instanceValue;
private boolean showMediaOnly;
private DisplayStatusFragment displayStatusFragment;
private TextView new_data;
public DisplayStatusFragment(){
displayStatusFragment = this;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -90,7 +98,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
tag = bundle.getString("tag", null);
hideHeader = bundle.getBoolean("hideHeader", false);
showMediaOnly = bundle.getBoolean("showMediaOnly",false);
instanceValue = bundle.getString("hideHeaderValue", null);
if( bundle.containsKey("statuses")){
ArrayList<Parcelable> statusesReceived = bundle.getParcelableArrayList("statuses");
assert statusesReceived != null;
@ -105,13 +112,13 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
firstLoad = true;
swiped = false;
isOnWifi = Helper.isOnWIFI(context);
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipeContainer);
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
lv_status = (ListView) rootView.findViewById(R.id.lv_status);
tootsPerPage = sharedpreferences.getInt(Helper.SET_TOOTS_PER_PAGE, 40);
mainLoader = (RelativeLayout) rootView.findViewById(R.id.loader);
nextElementLoader = (RelativeLayout) rootView.findViewById(R.id.loading_next_status);
textviewNoAction = (RelativeLayout) rootView.findViewById(R.id.no_action);
@ -119,7 +126,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
nextElementLoader.setVisibility(View.GONE);
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, this.statuses);
lv_status.setAdapter(statusListAdapter);
new_data = (TextView) rootView.findViewById(R.id.new_data);
if( !comesFromSearch){
//Hide account header when scrolling for ShowAccountActivity
@ -167,7 +174,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4,
R.color.mastodonC2,
R.color.mastodonC3);
@ -187,6 +193,24 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
textviewNoAction.setVisibility(View.VISIBLE);
}
new_data.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if( statusesTmp != null){
boolean isOnWifi = Helper.isOnWIFI(context);
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
statuses = new ArrayList<>();
for(Status status: statusesTmp){
statuses.add(status);
}
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, statuses);
lv_status.setAdapter(statusListAdapter);
statusesTmp = new ArrayList<>();
}
new_data.setVisibility(View.GONE);
}
});
return rootView;
}
@ -199,6 +223,24 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
@Override
public void onResume() {
super.onResume();
//New data are available
if (getUserVisibleHint() && statusesTmp != null && statusesTmp.size() > 0 ) {
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean isOnWifi = Helper.isOnWIFI(context);
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
statuses = new ArrayList<>();
for(Status status: statusesTmp){
statuses.add(status);
}
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, statuses);
lv_status.setAdapter(statusListAdapter);
statusesTmp = new ArrayList<>();
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
@ -215,12 +257,12 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
@Override
public void onRetrieveFeeds(APIResponse apiResponse) {
public void onRetrieveFeeds(APIResponse apiResponse, boolean refreshData) {
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
//Discards 404 - error which can often happen due to toots which have been deleted
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
if( apiResponse.getError() != null && !apiResponse.getError().getError().startsWith("404 -")){
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, apiResponse.getError().getError(),Toast.LENGTH_LONG).show();
@ -229,8 +271,70 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
flag_loading = false;
return;
}
flag_loading = (apiResponse.getMax_id() == null );
List<Status> statuses = apiResponse.getStatuses();
if( type == RetrieveFeedsAsyncTask.Type.HOME){
SharedPreferences.Editor editor = sharedpreferences.edit();
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
editor.putString(Helper.LAST_BUBBLE_REFRESH_HOME+ userId,Helper.dateToString(context, new Date()));
editor.apply();
String bubble_max_id = sharedpreferences.getString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, null);
if( refreshData ) {
max_id = apiResponse.getMax_id();
manageStatus(statuses, max_id);
if( apiResponse.getSince_id() != null) {
editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, apiResponse.getSince_id());
editor.apply();
}
}else {
int countData = 0;
if( bubble_max_id != null) {
for (Status st : statuses) {
if (st.getId().trim().equals(bubble_max_id.trim()))
break;
countData++;
}
}
if( !displayStatusFragment.getUserVisibleHint()){
((MainActivity)context).updateHomeCounter(countData);
if( countData > 0){
max_id = null;
firstLoad = true;
statusesTmp = new ArrayList<>();
for(Status tmpStatus: statuses){
this.statusesTmp.add(tmpStatus);
}
}
if( apiResponse.getSince_id() != null) {
editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, apiResponse.getSince_id());
editor.apply();
}
}else {
if( statuses != null && statuses.size() > 0 && countData > 0) {
max_id = null;
firstLoad = true;
statusesTmp = new ArrayList<>();
for(Status tmpStatus: statuses){
this.statusesTmp.add(tmpStatus);
}
new_data.setVisibility(View.VISIBLE);
}
}
}
}else {
max_id = apiResponse.getMax_id();
manageStatus(statuses, max_id);
}
}
private void manageStatus(List<Status> statuses, String max_id){
flag_loading = (max_id == null );
if( !swiped && firstLoad && (statuses == null || statuses.size() == 0))
textviewNoAction.setVisibility(View.VISIBLE);
else
@ -240,7 +344,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
lv_status.setAdapter(statusListAdapter);
swiped = false;
}
max_id = apiResponse.getMax_id();
if( statuses != null && statuses.size() > 0) {
for(Status tmpStatus: statuses){
this.statuses.add(tmpStatus);
@ -258,7 +361,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
Account currentAccount = new AccountDAO(context, db).getAccountByID(userId);
if( currentAccount != null && firstLoad){
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + currentAccount.getId(), statuses.get(0).getId());
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + currentAccount.getId(), max_id);
editor.apply();
}
}
@ -273,7 +376,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
new RetrieveRepliesAsyncTask(context, statuses, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
}
public void scrollToTop(){
@ -295,4 +397,24 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
}
statusListAdapter.notifyDataSetChanged();
}
public void update() {
if( context != null) {
asyncTask = new RetrieveFeedsAsyncTask(context, type, null, false, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
public void refreshData(){
if(context != null && this.statusesTmp != null && this.statusesTmp.size() > 0){
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean isOnWifi = Helper.isOnWIFI(context);
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
statuses = new ArrayList<>();
for(Status status: statusesTmp){
statuses.add(status);
}
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, statuses);
lv_status.setAdapter(statusListAdapter);
statusesTmp = new ArrayList<>();
}
}
}

View File

@ -32,7 +32,6 @@ import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v7.widget.SwitchCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -94,6 +93,19 @@ public class SettingsFragment extends Fragment {
}
});
boolean bubble_counter = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
final CheckBox set_bubble_counter = (CheckBox) rootView.findViewById(R.id.set_bubble_counter);
set_bubble_counter.setChecked(bubble_counter);
set_bubble_counter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SET_BUBBLE_COUNTER, set_bubble_counter.isChecked());
editor.apply();
}
});
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
final CheckBox set_show_error_messages = (CheckBox) rootView.findViewById(R.id.set_show_error_messages);
set_show_error_messages.setChecked(show_error_messages);

View File

@ -176,6 +176,10 @@ public class Helper {
public static final String SHOW_BATTERY_SAVER_MESSAGE = "show_battery_saver_message";
public static final String LAST_NOTIFICATION_MAX_ID = "last_notification_max_id";
public static final String LAST_HOMETIMELINE_MAX_ID = "last_hometimeline_max_id";
public static final String LAST_BUBBLE_REFRESH_NOTIF = "last_bubble_refresh_notif";
public static final String LAST_BUBBLE_REFRESH_HOME = "last_bubble_refresh_home";
public static final String LAST_MAX_ID_BUBBLE_NOTIF = "last_max_id_bubble_notif";
public static final String LAST_MAX_ID_BUBBLE_HOME = "last_max_id_bubble_home";
public static final String CLIP_BOARD = "clipboard";
//Notifications
public static final int NOTIFICATION_INTENT = 1;
@ -199,6 +203,7 @@ public class Helper {
public static final String SET_ICON_SIZE = "set_icon_size";
public static final String SET_PREVIEW_REPLIES = "set_preview_replies";
public static final String SET_PREVIEW_REPLIES_PP = "set_preview_replies_pp";
public static final String SET_BUBBLE_COUNTER = "set_bubble_counter";
public static final int ATTACHMENT_ALWAYS = 1;
public static final int ATTACHMENT_WIFI = 2;
public static final int ATTACHMENT_ASK = 3;

View File

@ -21,5 +21,5 @@ import fr.gouv.etalab.mastodon.client.APIResponse;
* Interface when status have been retrieved
*/
public interface OnRetrieveFeedsInterface {
void onRetrieveFeeds(APIResponse apiResponse);
void onRetrieveFeeds(APIResponse apiResponse, boolean refreshData);
}

View File

@ -21,5 +21,5 @@ import fr.gouv.etalab.mastodon.client.APIResponse;
* Interface when notifications have been retrieved
*/
public interface OnRetrieveNotificationsInterface {
void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId);
void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId, boolean refreshData);
}

View File

@ -133,7 +133,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
@Override
public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId) {
public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId, boolean refreshData) {
List<Notification> notifications = apiResponse.getNotifications();
if( apiResponse.getError() != null || notifications == null || notifications.size() == 0)
@ -257,7 +257,6 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
}
}
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, apiResponse.getMax_id());
editor.apply();

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/mastodonC2" />
<padding android:left="2dp" android:right="2dp"/>
<corners android:radius="3dp" />
</shape>

View File

@ -79,43 +79,16 @@
android:gravity="end"/>
</LinearLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="60dp"
app:tabGravity="fill"
app:tabMaxWidth="0dp"
app:tabSelectedTextColor="?attr/colorAccent">
<android.support.design.widget.TabItem
android:id="@+id/tab_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/ic_action_home_tl"/>
<android.support.design.widget.TabItem
android:id="@+id/tab_notification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/ic_notifications_tl"/>
<android.support.design.widget.TabItem
android:id="@+id/tab_local"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/ic_action_users_tl"/>
<android.support.design.widget.TabItem
android:id="@+id/tab_global"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/ic_action_globe_tl"/>
</android.support.design.widget.TabLayout>
</LinearLayout>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="60dp"
app:tabGravity="fill"
app:tabMaxWidth="0dp"
app:tabSelectedTextColor="?attr/colorAccent"/>
</android.support.design.widget.AppBarLayout>

View File

@ -79,5 +79,19 @@
android:layout_height="match_parent"
android:indeterminate="true" />
</RelativeLayout>
<TextView
android:visibility="gone"
android:background="@color/mastodonC3"
android:textColor="@color/mastodonC1"
android:clickable="true"
android:padding="10dp"
android:gravity="center"
android:text="@string/new_data"
android:layout_alignParentBottom="true"
android:id="@+id/new_data"
android:layout_width="match_parent"
android:textSize="18sp"
android:layout_height="wrap_content"/>
</RelativeLayout>

View File

@ -58,6 +58,12 @@
android:text="@string/set_auto_store_toot"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/set_bubble_counter"
android:layout_width="wrap_content"
android:text="@string/set_bubble_counter"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/set_preview_reply"
android:layout_width="wrap_content"

View File

@ -77,5 +77,20 @@
android:layout_height="match_parent"
android:indeterminate="true" />
</RelativeLayout>
<TextView
android:visibility="gone"
android:padding="10dp"
android:background="@color/mastodonC3"
android:textColor="@color/mastodonC1"
android:clickable="true"
android:gravity="center"
android:text="@string/new_data"
android:layout_alignParentBottom="true"
android:id="@+id/new_data"
android:layout_width="match_parent"
android:textSize="18sp"
android:layout_height="wrap_content"/>
</RelativeLayout>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017 Thomas Schneider
This file is a part of Mastalab
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License along with Mastalab; if not,
see <http://www.gnu.org/licenses>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<ImageView
android:id="@+id/tab_icon"
android:layout_gravity="center"
android:layout_width="30dp"
android:layout_height="30dp" />
<TextView
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:id="@+id/tab_counter"
android:visibility="gone"
android:gravity="center"
android:textSize="14sp"
android:minWidth="30dp"
android:minHeight="30dp"
android:textColor="@color/mastodonC1"
android:background="@drawable/shape_counter"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@ -43,72 +43,41 @@
android:theme="@style/AppThemeDark_NoActionBar"
app:popupTheme="?attr/popupOverlay">
<LinearLayout
android:id="@+id/toolbar_search_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/toolbar_search_container"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/pp_actionBar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:textSize="16sp"
android:id="@+id/toolbar_title" />
<android.support.v7.widget.SearchView
android:background="@null"
android:id="@+id/toolbar_search"
android:gravity="end"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="25dp"
app:tabSelectedTextColor="?attr/colorAccent"
>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tab_home"
android:icon="@drawable/ic_action_home_tl"/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tab_notification"
android:icon="@drawable/ic_notifications_tl"/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tab_local"
android:icon="@drawable/ic_action_users_tl"/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tab_global"
android:icon="@drawable/ic_action_globe_tl"/>
</android.support.design.widget.TabLayout>
android:layout_height="40dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/pp_actionBar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:textSize="16sp"
android:id="@+id/toolbar_title" />
<android.support.v7.widget.SearchView
android:background="@null"
android:id="@+id/toolbar_search"
android:gravity="end"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="25dp"
app:tabSelectedTextColor="?attr/colorAccent"
/>
</android.support.design.widget.AppBarLayout>

View File

@ -79,5 +79,19 @@
android:layout_height="match_parent"
android:indeterminate="true" />
</RelativeLayout>
<TextView
android:background="@color/mastodonC3"
android:textColor="@color/mastodonC1"
android:clickable="true"
android:visibility="gone"
android:padding="10dp"
android:gravity="center"
android:text="@string/new_data"
android:layout_alignParentBottom="true"
android:id="@+id/new_data"
android:layout_width="match_parent"
android:textSize="16sp"
android:layout_height="wrap_content"/>
</RelativeLayout>

View File

@ -58,6 +58,12 @@
android:text="@string/set_auto_store_toot"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/set_bubble_counter"
android:layout_width="wrap_content"
android:text="@string/set_bubble_counter"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/set_preview_reply"
android:layout_width="wrap_content"

View File

@ -77,5 +77,20 @@
android:layout_height="match_parent"
android:indeterminate="true" />
</RelativeLayout>
<TextView
android:visibility="gone"
android:background="@color/mastodonC3"
android:textColor="@color/mastodonC1"
android:clickable="true"
android:padding="10dp"
android:gravity="center"
android:text="@string/new_data"
android:layout_alignParentBottom="true"
android:id="@+id/new_data"
android:layout_width="match_parent"
android:textSize="16sp"
android:layout_height="wrap_content"/>
</RelativeLayout>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017 Thomas Schneider
This file is a part of Mastalab
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License along with Mastalab; if not,
see <http://www.gnu.org/licenses>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<ImageView
android:id="@+id/tab_icon"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:id="@+id/tab_counter"
android:visibility="gone"
android:gravity="center"
android:textSize="10sp"
android:minWidth="20dp"
android:minHeight="20dp"
android:textColor="@color/mastodonC1"
android:background="@drawable/shape_counter"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@ -57,6 +57,8 @@
<string name="shared_via">Partagé via Mastalab</string>
<string name="replies">Réponses</string>
<string name="username">Nom d\'utilisateur</string>
<string name="new_data">De nouvelles données sont disponibles ! Souhaitez-vous les afficher ?</string>
<!--- Menu -->
<string name="home_menu">Accueil</string>
<string name="local_menu">Fil public local</string>
@ -283,6 +285,7 @@
<string name="set_display_reply">Afficher le message précédent lors d\'une réponse</string>
<string name="set_folder_title">Destination : </string>
<string name="set_auto_store_toot">Enregistrer les brouillons automatiquement</string>
<string name="set_bubble_counter">Afficher les compteurs</string>
<string name="set_auto_add_media_url">Ajouter l\'URL des médias dans les pouets</string>
<string name="settings_title_notifications">Gestion des notifications</string>
<string name="set_notif_follow">Notifier lorsque quelquun me suit</string>

View File

@ -59,6 +59,8 @@
<string name="shared_via">Shared via Mastalab</string>
<string name="replies">Replies</string>
<string name="username">User name</string>
<string name="new_data">New data are available! Do you want to display them?</string>
<!--- Menu -->
<string name="home_menu">Home</string>
<string name="local_menu">Local timeline</string>
@ -289,6 +291,7 @@
<string name="set_display_reply">Display previous message in responses</string>
<string name="set_folder_title">Path: </string>
<string name="set_auto_store_toot">Save drafts automatically</string>
<string name="set_bubble_counter">Display counters</string>
<string name="set_auto_add_media_url">Add URL of media in toots</string>
<string name="settings_title_notifications">Manage notifications</string>
<string name="set_notif_follow">Notify when someone follows you</string>