Merged tom79/mastodon_etalab into master
|
@ -7,8 +7,8 @@ android {
|
|||
applicationId "fr.gouv.etalab.mastodon"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 25
|
||||
versionCode 48
|
||||
versionName "1.4.8"
|
||||
versionCode 49
|
||||
versionName "1.4.9-beta-1"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
|
|
@ -15,26 +15,31 @@
|
|||
package fr.gouv.etalab.mastodon.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
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.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.support.design.widget.NavigationView;
|
||||
|
@ -61,12 +66,13 @@ 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.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveMetaDataAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoByIDAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||
|
@ -75,7 +81,9 @@ import fr.gouv.etalab.mastodon.fragments.DisplayFollowRequestSentFragment;
|
|||
import fr.gouv.etalab.mastodon.fragments.DisplayNotificationsFragment;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayScheduledTootsFragment;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveMetaDataInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnUpdateAccountInfoInterface;
|
||||
import fr.gouv.etalab.mastodon.services.StreamingService;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask;
|
||||
|
@ -100,7 +108,7 @@ import android.support.v4.app.FragmentStatePagerAdapter;
|
|||
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
implements NavigationView.OnNavigationItemSelectedListener, OnUpdateAccountInfoInterface {
|
||||
implements NavigationView.OnNavigationItemSelectedListener, OnUpdateAccountInfoInterface, OnRetrieveMetaDataInterface {
|
||||
|
||||
private FloatingActionButton toot;
|
||||
private HashMap<String, String> tagTile = new HashMap<>();
|
||||
|
@ -119,7 +127,8 @@ public class MainActivity extends AppCompatActivity
|
|||
|
||||
private DisplayStatusFragment homeFragment;
|
||||
private DisplayNotificationsFragment notificationsFragment;
|
||||
|
||||
private BroadcastReceiver receive_data;
|
||||
private boolean display_local, display_global;
|
||||
|
||||
public MainActivity() {
|
||||
}
|
||||
|
@ -127,7 +136,47 @@ public class MainActivity extends AppCompatActivity
|
|||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
|
||||
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
receive_data = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
StreamingService.EventStreaming eventStreaming = (StreamingService.EventStreaming) intent.getSerializableExtra("eventStreaming");
|
||||
if( eventStreaming == StreamingService.EventStreaming.NOTIFICATION){
|
||||
if(notificationsFragment != null){
|
||||
if(notificationsFragment.getUserVisibleHint() && isActivityVisible()){
|
||||
notificationsFragment.showNewContent();
|
||||
}else{
|
||||
notificationsFragment.refresh();
|
||||
}
|
||||
}
|
||||
}else if(eventStreaming == StreamingService.EventStreaming.UPDATE){
|
||||
if( homeFragment != null){
|
||||
if(homeFragment.getUserVisibleHint() && isActivityVisible()){
|
||||
homeFragment.showNewContent();
|
||||
}else{
|
||||
homeFragment.refresh();
|
||||
}
|
||||
}
|
||||
}else if(eventStreaming == StreamingService.EventStreaming.DELETE){
|
||||
String id = b.getString("id");
|
||||
if(notificationsFragment != null) {
|
||||
if (notificationsFragment.getUserVisibleHint()) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
updateNotifCounter();
|
||||
updateHomeCounter();
|
||||
}
|
||||
};
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
|
||||
|
||||
|
||||
|
||||
final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
if( theme == Helper.THEME_LIGHT){
|
||||
|
@ -137,6 +186,9 @@ public class MainActivity extends AppCompatActivity
|
|||
}
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
display_local = sharedpreferences.getBoolean(Helper.SET_DISPLAY_LOCAL, true);
|
||||
display_global = sharedpreferences.getBoolean(Helper.SET_DISPLAY_GLOBAL, true);
|
||||
|
||||
//Test if user is still log in
|
||||
if( ! Helper.isLoggedIn(getApplicationContext())) {
|
||||
//It is not, the user is redirected to the login page
|
||||
|
@ -145,7 +197,16 @@ public class MainActivity extends AppCompatActivity
|
|||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
List<Account> accounts = new AccountDAO(getApplicationContext(), db).getAllAccount();
|
||||
if( accounts != null){
|
||||
for (Account account: accounts) {
|
||||
Intent intent = new Intent(getApplicationContext(), StreamingService.class);
|
||||
intent.putExtra("accountId", account.getId());
|
||||
intent.putExtra("accountAcct", account.getAcct());
|
||||
startService(intent);
|
||||
}
|
||||
}
|
||||
Helper.fillMapEmoji(getApplicationContext());
|
||||
//Here, the user is authenticated
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
|
@ -194,8 +255,10 @@ public class MainActivity extends AppCompatActivity
|
|||
|
||||
tabLayout.addTab(tabHome);
|
||||
tabLayout.addTab(tabNotif);
|
||||
tabLayout.addTab(tabLocal);
|
||||
tabLayout.addTab(tabPublic);
|
||||
if( display_local)
|
||||
tabLayout.addTab(tabLocal);
|
||||
if( display_global)
|
||||
tabLayout.addTab(tabPublic);
|
||||
|
||||
viewPager = (ViewPager) findViewById(R.id.viewpager);
|
||||
main_app_container = (RelativeLayout) findViewById(R.id.main_app_container);
|
||||
|
@ -203,7 +266,6 @@ public class MainActivity extends AppCompatActivity
|
|||
(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) {
|
||||
|
@ -222,29 +284,32 @@ public class MainActivity extends AppCompatActivity
|
|||
main_app_container.setVisibility(View.GONE);
|
||||
viewPager.setVisibility(View.VISIBLE);
|
||||
Helper.switchLayout(MainActivity.this);
|
||||
switch (tab.getPosition()){
|
||||
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";
|
||||
item = navigationView.getMenu().findItem(R.id.nav_local);
|
||||
break;
|
||||
case 3:
|
||||
if( tab.getPosition() == 0) {
|
||||
item = navigationView.getMenu().findItem(R.id.nav_home);
|
||||
fragmentTag = "HOME_TIMELINE";
|
||||
if (homeFragment != null && Helper.getUnreadToots(getApplicationContext(), null) > 0) {
|
||||
homeFragment.refresh();
|
||||
}
|
||||
Helper.cacheStatusClear(getApplicationContext(), null);
|
||||
updateHomeCounter();
|
||||
}else if( tab.getPosition() == 1) {
|
||||
fragmentTag = "NOTIFICATIONS";
|
||||
item = navigationView.getMenu().findItem(R.id.nav_notification);
|
||||
if (notificationsFragment != null && Helper.getUnreadNotifications(getApplicationContext(), null) > 0) {
|
||||
notificationsFragment.refresh();
|
||||
}
|
||||
Helper.cacheNotificationsClear(getApplicationContext(), null);
|
||||
updateNotifCounter();
|
||||
}else if( tab.getPosition() == 2 && display_local) {
|
||||
|
||||
fragmentTag = "LOCAL_TIMELINE";
|
||||
item = navigationView.getMenu().findItem(R.id.nav_local);
|
||||
}else if( tab.getPosition() == 2 && !display_local) {
|
||||
item = navigationView.getMenu().findItem(R.id.nav_global);
|
||||
fragmentTag = "PUBLIC_TIMELINE";
|
||||
break;
|
||||
}else if( tab.getPosition() == 3){
|
||||
item = navigationView.getMenu().findItem(R.id.nav_global);
|
||||
fragmentTag = "PUBLIC_TIMELINE";
|
||||
}
|
||||
if( item != null){
|
||||
toolbarTitle.setText(item.getTitle());
|
||||
|
@ -281,9 +346,15 @@ public class MainActivity extends AppCompatActivity
|
|||
Fragment fragment = (Fragment) viewPager.getAdapter().instantiateItem(viewPager, tab.getPosition());
|
||||
switch (tab.getPosition()){
|
||||
case 0:
|
||||
DisplayStatusFragment displayStatusFragment = ((DisplayStatusFragment) fragment);
|
||||
if( displayStatusFragment != null )
|
||||
displayStatusFragment.scrollToTop();
|
||||
Helper.cacheStatusClear(getApplicationContext(), null);
|
||||
updateHomeCounter();
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
DisplayStatusFragment displayStatusFragment = ((DisplayStatusFragment) fragment);
|
||||
displayStatusFragment = ((DisplayStatusFragment) fragment);
|
||||
if( displayStatusFragment != null )
|
||||
displayStatusFragment.scrollToTop();
|
||||
break;
|
||||
|
@ -291,6 +362,8 @@ public class MainActivity extends AppCompatActivity
|
|||
DisplayNotificationsFragment displayNotificationsFragment = ((DisplayNotificationsFragment) fragment);
|
||||
if( displayNotificationsFragment != null )
|
||||
displayNotificationsFragment.scrollToTop();
|
||||
Helper.cacheNotificationsClear(getApplicationContext(), null);
|
||||
updateNotifCounter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -354,7 +427,11 @@ public class MainActivity extends AppCompatActivity
|
|||
Intent intent = new Intent(MainActivity.this, SearchResultActivity.class);
|
||||
intent.putExtra("search", query);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
toolbar_search.setQuery("", false);
|
||||
toolbar_search.setIconified(true);
|
||||
toolbarTitle.setVisibility(View.VISIBLE);
|
||||
pp_actionBar.setVisibility(View.VISIBLE);
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
|
@ -421,15 +498,14 @@ public class MainActivity extends AppCompatActivity
|
|||
.diskCache(new UnlimitedDiskCache(cacheDir))
|
||||
.build();
|
||||
imageLoader.init(configImg);
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
options = new DisplayImageOptions.Builder().displayer(new RoundedBitmapDisplayer(90)).cacheInMemory(false)
|
||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||
|
||||
|
||||
headerLayout = navigationView.getHeaderView(0);
|
||||
|
||||
String prefKeyOauthTokenT = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||
Account account = new AccountDAO(getApplicationContext(), db).getAccountByToken(prefKeyOauthTokenT);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(userId);
|
||||
updateHeaderAccountInfo(MainActivity.this, account, headerLayout, imageLoader, options);
|
||||
loadPPInActionBar(MainActivity.this, account.getAvatar());
|
||||
//Locked account can see follow request
|
||||
|
@ -545,6 +621,21 @@ public class MainActivity extends AppCompatActivity
|
|||
String sharedSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
|
||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
if (sharedText != null) {
|
||||
/* Some apps don't send the URL as the first part of the EXTRA_TEXT,
|
||||
the BBC News app being one such, in this case find where the URL
|
||||
is and strip that out into sharedText.
|
||||
*/
|
||||
Matcher matcher;
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
|
||||
matcher = Patterns.WEB_URL.matcher(sharedText);
|
||||
else
|
||||
matcher = Helper.urlPattern.matcher(sharedText);
|
||||
while (matcher.find()){
|
||||
int matchStart = matcher.start(1);
|
||||
int matchEnd = matcher.end();
|
||||
sharedText = sharedText.substring(matchStart, matchEnd);
|
||||
}
|
||||
new RetrieveMetaDataAsyncTask(sharedText, MainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
Intent intentToot = new Intent(getApplicationContext(), TootActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("sharedSubject", sharedSubject);
|
||||
|
@ -599,6 +690,7 @@ public class MainActivity extends AppCompatActivity
|
|||
//Hide search bar on back pressed
|
||||
if( !toolbar_search.isIconified()){
|
||||
toolbar_search.setIconified(true);
|
||||
return;
|
||||
}
|
||||
if( viewPager.getVisibility() == View.VISIBLE){
|
||||
if (stackBack.size() > 1) {
|
||||
|
@ -615,7 +707,7 @@ public class MainActivity extends AppCompatActivity
|
|||
unCheckAllMenuItems(navigationView);
|
||||
toot.setVisibility(View.VISIBLE);
|
||||
//Manages theme for icon colors
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
if( theme == Helper.THEME_DARK){
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.ic_reply,R.color.dark_text);
|
||||
|
@ -800,22 +892,25 @@ 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);
|
||||
}
|
||||
MainActivity.activityResumed();
|
||||
updateNotifCounter();
|
||||
updateHomeCounter();
|
||||
//Proceeds to update of the authenticated account
|
||||
if(Helper.isLoggedIn(getApplicationContext()))
|
||||
new UpdateAccountInfoByIDAsyncTask(getApplicationContext(), MainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
MainActivity.activityPaused();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy(){
|
||||
super.onDestroy();
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
|
||||
}
|
||||
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
@Override
|
||||
|
@ -838,20 +933,25 @@ public class MainActivity extends AppCompatActivity
|
|||
}
|
||||
toolbarTitle.setText(item.getTitle());
|
||||
if (id == R.id.nav_home) {
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(0).select();
|
||||
if( tabLayout.getSelectedTabPosition() != 0)
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(0).select();
|
||||
return true;
|
||||
} else if( id == R.id.nav_notification){
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(1).select();
|
||||
if( tabLayout.getSelectedTabPosition() != 1)
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(1).select();
|
||||
return true;
|
||||
}else if (id == R.id.nav_local) {
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(2).select();
|
||||
|
||||
if( tabLayout.getSelectedTabPosition() != 2)
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(2).select();
|
||||
return true;
|
||||
} else if (id == R.id.nav_global) {
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(3).select();
|
||||
if( tabLayout.getSelectedTabPosition() != 3)
|
||||
//noinspection ConstantConditions
|
||||
tabLayout.getTabAt(3).select();
|
||||
return true;
|
||||
}
|
||||
DisplayStatusFragment statusFragment;
|
||||
|
@ -948,7 +1048,16 @@ public class MainActivity extends AppCompatActivity
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveMetaData(boolean error, String image, String title, String description) {
|
||||
if( !error) {
|
||||
Intent intentSendImage = new Intent(Helper.RECEIVE_PICTURE);
|
||||
intentSendImage.putExtra("image", image);
|
||||
intentSendImage.putExtra("title", title);
|
||||
intentSendImage.putExtra("description", description);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentSendImage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -973,26 +1082,29 @@ public class MainActivity extends AppCompatActivity
|
|||
//Selection comes from another menu, no action to do
|
||||
DisplayStatusFragment statusFragment;
|
||||
Bundle bundle = new Bundle();
|
||||
switch (position) {
|
||||
case 0:
|
||||
homeFragment = new DisplayStatusFragment();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.HOME);
|
||||
homeFragment.setArguments(bundle);
|
||||
return homeFragment;
|
||||
case 1:
|
||||
notificationsFragment = new DisplayNotificationsFragment();
|
||||
return notificationsFragment;
|
||||
case 2:
|
||||
if (position == 0) {
|
||||
homeFragment = new DisplayStatusFragment();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.HOME);
|
||||
homeFragment.setArguments(bundle);
|
||||
return homeFragment;
|
||||
}else if( position == 1) {
|
||||
notificationsFragment = new DisplayNotificationsFragment();
|
||||
return notificationsFragment;
|
||||
}else if( position == 2 && display_local) {
|
||||
statusFragment = new DisplayStatusFragment();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.LOCAL);
|
||||
statusFragment.setArguments(bundle);
|
||||
return statusFragment;
|
||||
case 3:
|
||||
}else if( position == 2 && !display_local){
|
||||
statusFragment = new DisplayStatusFragment();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.PUBLIC);
|
||||
statusFragment.setArguments(bundle);
|
||||
return statusFragment;
|
||||
|
||||
}else if (position == 3){
|
||||
statusFragment = new DisplayStatusFragment();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.PUBLIC);
|
||||
statusFragment.setArguments(bundle);
|
||||
return statusFragment;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1003,40 +1115,8 @@ 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(60)) {
|
||||
|
||||
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(60)) {
|
||||
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){
|
||||
public void updateHomeCounter(){
|
||||
if( tabLayout.getTabAt(0) == null )
|
||||
return;
|
||||
//noinspection ConstantConditions
|
||||
|
@ -1044,20 +1124,17 @@ public class MainActivity extends AppCompatActivity
|
|||
if( tabHome == null)
|
||||
return;
|
||||
TextView tabCounterHome = (TextView) tabHome.findViewById(R.id.tab_counter);
|
||||
tabCounterHome.setText(String.valueOf(newHomeCount));
|
||||
if( newHomeCount > 0){
|
||||
tabCounterHome.setText(String.valueOf(Helper.getUnreadToots(getApplicationContext(), null)));
|
||||
if( Helper.getUnreadToots(getApplicationContext(), null) > 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);
|
||||
tabCounterHome.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
tabCounterHome.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateNotifCounter(int newNotifCount){
|
||||
public void updateNotifCounter(){
|
||||
if(tabLayout.getTabAt(1) == null)
|
||||
return;
|
||||
//noinspection ConstantConditions
|
||||
|
@ -1065,15 +1142,25 @@ public class MainActivity extends AppCompatActivity
|
|||
if( tabNotif == null)
|
||||
return;
|
||||
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);
|
||||
tabCounterNotif.setText(String.valueOf(Helper.getUnreadNotifications(getApplicationContext(), null)));
|
||||
if( Helper.getUnreadNotifications(getApplicationContext(), null) > 0){
|
||||
tabCounterNotif.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
tabCounterNotif.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isActivityVisible() {
|
||||
return activityVisible;
|
||||
}
|
||||
|
||||
private static void activityResumed() {
|
||||
activityVisible = true;
|
||||
}
|
||||
|
||||
private static void activityPaused() {
|
||||
activityVisible = false;
|
||||
}
|
||||
|
||||
private static boolean activityVisible;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<application
|
||||
android:name="fr.gouv.etalab.mastodon.activities.MainApplication"
|
||||
|
@ -34,10 +35,18 @@
|
|||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppThemeDark">
|
||||
<service
|
||||
android:name="fr.gouv.etalab.mastodon.services.StreamingService"
|
||||
android:exported="false"/>
|
||||
<receiver android:name="fr.gouv.etalab.mastodon.services.BootService" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<activity
|
||||
android:name="fr.gouv.etalab.mastodon.activities.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode = "adjustResize"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:theme="@style/AppThemeDark_NoActionBar">
|
||||
|
@ -70,7 +79,6 @@
|
|||
<activity android:name="fr.gouv.etalab.mastodon.activities.HashTagActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:noHistory="true"
|
||||
android:label="@string/app_name"
|
||||
/>
|
||||
<activity android:name="fr.gouv.etalab.mastodon.activities.WebviewConnectActivity"
|
||||
|
@ -82,7 +90,6 @@
|
|||
android:label="@string/app_name"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:launchMode="singleTask"
|
||||
android:noHistory="true"
|
||||
/>
|
||||
<activity android:name="fr.gouv.etalab.mastodon.activities.MediaActivity"
|
||||
android:label="@string/app_name"
|
||||
|
@ -127,6 +134,11 @@
|
|||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme_NoActionBar"
|
||||
/>
|
||||
<activity android:name="fr.gouv.etalab.mastodon.activities.EditProfileActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
/>
|
||||
<activity
|
||||
android:name="fr.gouv.etalab.mastodon.activities.SplashActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
|
|
|
@ -2424,4 +2424,261 @@ digit_one, 0x0031
|
|||
digit_zero, 0x0030
|
||||
family_man_woman_boy, 0x1f468,0x1f469,0x1f466
|
||||
couple_with_heart_woman_man, 0x1f469,0x2764,0x1f468
|
||||
kiss_woman_man, 0x1f469,0x2764,0x1f48b,0x1f468
|
||||
kiss_woman_man, 0x1f469,0x2764,0x1f48b,0x1f468
|
||||
ad, 0x1f1e6,0x1f1e9
|
||||
ao, 0x1f1e6,0x1f1f4
|
||||
af, 0x1f1e6,0x1f1eb
|
||||
ai, 0x1f1e6,0x1f1ee
|
||||
aq, 0x1f1e6,0x1f1f6
|
||||
ag, 0x1f1e6,0x1f1ec
|
||||
al, 0x1f1e6,0x1f1f1
|
||||
ar, 0x1f1e6,0x1f1f7
|
||||
as, 0x1f1e6,0x1f1f8
|
||||
am, 0x1f1e6,0x1f1f2
|
||||
aw, 0x1f1e6,0x1f1fc
|
||||
au, 0x1f1e6,0x1f1fa
|
||||
at, 0x1f1e6,0x1f1f9
|
||||
ax, 0x1f1e6,0x1f1fd
|
||||
az, 0x1f1e6,0x1f1ff
|
||||
bs, 0x1f1e7,0x1f1f8
|
||||
bh, 0x1f1e7,0x1f1ed
|
||||
bd, 0x1f1e7,0x1f1e9
|
||||
bb, 0x1f1e7,0x1f1e7
|
||||
by, 0x1f1e7,0x1f1fe
|
||||
be, 0x1f1e7,0x1f1ea
|
||||
bz, 0x1f1e7,0x1f1ff
|
||||
bj, 0x1f1e7,0x1f1ef
|
||||
bm, 0x1f1e7,0x1f1f2
|
||||
bt, 0x1f1e7,0x1f1f9
|
||||
bo, 0x1f1e7,0x1f1f4
|
||||
ba, 0x1f1e7,0x1f1e6
|
||||
bw, 0x1f1e7,0x1f1fc
|
||||
br, 0x1f1e7,0x1f1f7
|
||||
io, 0x1f1ee,0x1f1f4
|
||||
vg, 0x1f1fb,0x1f1ec
|
||||
bn, 0x1f1e7,0x1f1f3
|
||||
bg, 0x1f1e7,0x1f1ec
|
||||
bf, 0x1f1e7,0x1f1eb
|
||||
bi, 0x1f1e7,0x1f1ee
|
||||
kh, 0x1f1f0,0x1f1ed
|
||||
cm, 0x1f1e8,0x1f1f2
|
||||
ca, 0x1f1e8,0x1f1e6
|
||||
ic, 0x1f1ee,0x1f1e8
|
||||
cv, 0x1f1e8,0x1f1fb
|
||||
bq, 0x1f1e7,0x1f1f6
|
||||
ky, 0x1f1f0,0x1f1fe
|
||||
cf, 0x1f1e8,0x1f1eb
|
||||
td, 0x1f1f9,0x1f1e9
|
||||
cl, 0x1f1e8,0x1f1f1
|
||||
cn, 0x1f1e8,0x1f1f3
|
||||
cx, 0x1f1e8,0x1f1fd
|
||||
cc, 0x1f1e8,0x1f1e8
|
||||
co, 0x1f1e8,0x1f1f4
|
||||
km, 0x1f1f0,0x1f1f2
|
||||
cg, 0x1f1e8,0x1f1ec
|
||||
cd, 0x1f1e8,0x1f1e9
|
||||
ck, 0x1f1e8,0x1f1f0
|
||||
cr, 0x1f1e8,0x1f1f7
|
||||
ci, 0x1f1e8,0x1f1ee
|
||||
hr, 0x1f1ed,0x1f1f7
|
||||
cu, 0x1f1e8,0x1f1fa
|
||||
cw, 0x1f1e8,0x1f1fc
|
||||
cy, 0x1f1e8,0x1f1fe
|
||||
cz, 0x1f1e8,0x1f1ff
|
||||
dk, 0x1f1e9,0x1f1f0
|
||||
dj, 0x1f1e9,0x1f1ef
|
||||
dm, 0x1f1e9,0x1f1f2
|
||||
do, 0x1f1e9,0x1f1f4
|
||||
ec, 0x1f1ea,0x1f1e8
|
||||
eg, 0x1f1ea,0x1f1ec
|
||||
sv, 0x1f1f8,0x1f1fb
|
||||
gq, 0x1f1ec,0x1f1f6
|
||||
er, 0x1f1ea,0x1f1f7
|
||||
ee, 0x1f1ea,0x1f1ea
|
||||
et, 0x1f1ea,0x1f1f9
|
||||
eu, 0x1f1ea,0x1f1fa
|
||||
fk, 0x1f1eb,0x1f1f0
|
||||
fo, 0x1f1eb,0x1f1f4
|
||||
fj, 0x1f1eb,0x1f1ef
|
||||
fi, 0x1f1eb,0x1f1ee
|
||||
fr, 0x1f1eb,0x1f1f7
|
||||
gf, 0x1f1ec,0x1f1eb
|
||||
pf, 0x1f1f5,0x1f1eb
|
||||
tf, 0x1f1f9,0x1f1eb
|
||||
ga, 0x1f1ec,0x1f1e6
|
||||
gb, 0x1f1ec,0x1f1e7
|
||||
gm, 0x1f1ec,0x1f1f2
|
||||
ge, 0x1f1ec,0x1f1ea
|
||||
de, 0x1f1e9,0x1f1ea
|
||||
gh, 0x1f1ec,0x1f1ed
|
||||
gi, 0x1f1ec,0x1f1ee
|
||||
gr, 0x1f1ec,0x1f1f7
|
||||
gl, 0x1f1ec,0x1f1f1
|
||||
gd, 0x1f1ec,0x1f1e9
|
||||
gp, 0x1f1ec,0x1f1f5
|
||||
gu, 0x1f1ec,0x1f1fa
|
||||
gt, 0x1f1ec,0x1f1f9
|
||||
gg, 0x1f1ec,0x1f1ec
|
||||
gn, 0x1f1ec,0x1f1f3
|
||||
gw, 0x1f1ec,0x1f1fc
|
||||
gy, 0x1f1ec,0x1f1fe
|
||||
ht, 0x1f1ed,0x1f1f9
|
||||
hn, 0x1f1ed,0x1f1f3
|
||||
hk, 0x1f1ed,0x1f1f0
|
||||
hu, 0x1f1ed,0x1f1fa
|
||||
is, 0x1f1ee,0x1f1f8
|
||||
in, 0x1f1ee,0x1f1f3
|
||||
id, 0x1f1ee,0x1f1e9
|
||||
ir, 0x1f1ee,0x1f1f7
|
||||
iq, 0x1f1ee,0x1f1f6
|
||||
ie, 0x1f1ee,0x1f1ea
|
||||
im, 0x1f1ee,0x1f1f2
|
||||
il, 0x1f1ee,0x1f1f1
|
||||
it, 0x1f1ee,0x1f1f9
|
||||
jm, 0x1f1ef,0x1f1f2
|
||||
jp, 0x1f1ef,0x1f1f5
|
||||
je, 0x1f1ef,0x1f1ea
|
||||
jo, 0x1f1ef,0x1f1f4
|
||||
kz, 0x1f1f0,0x1f1ff
|
||||
ke, 0x1f1f0,0x1f1ea
|
||||
ki, 0x1f1f0,0x1f1ee
|
||||
xk, 0x1f1fd,0x1f1f0
|
||||
kw, 0x1f1f0,0x1f1fc
|
||||
kg, 0x1f1f0,0x1f1ec
|
||||
la, 0x1f1f1,0x1f1e6
|
||||
lv, 0x1f1f1,0x1f1fb
|
||||
lb, 0x1f1f1,0x1f1e7
|
||||
ls, 0x1f1f1,0x1f1f8
|
||||
lr, 0x1f1f1,0x1f1f7
|
||||
ly, 0x1f1f1,0x1f1fe
|
||||
li, 0x1f1f1,0x1f1ee
|
||||
lt, 0x1f1f1,0x1f1f9
|
||||
lu, 0x1f1f1,0x1f1fa
|
||||
mo, 0x1f1f2,0x1f1f4
|
||||
mk, 0x1f1f2,0x1f1f0
|
||||
mg, 0x1f1f2,0x1f1ec
|
||||
mw, 0x1f1f2,0x1f1fc
|
||||
my, 0x1f1f2,0x1f1fe
|
||||
mv, 0x1f1f2,0x1f1fb
|
||||
ml, 0x1f1f2,0x1f1f1
|
||||
mt, 0x1f1f2,0x1f1f9
|
||||
mh, 0x1f1f2,0x1f1ed
|
||||
mq, 0x1f1f2,0x1f1f6
|
||||
mr, 0x1f1f2,0x1f1f7
|
||||
mu, 0x1f1f2,0x1f1fa
|
||||
yt, 0x1f1fe,0x1f1f9
|
||||
mx, 0x1f1f2,0x1f1fd
|
||||
fm, 0x1f1eb,0x1f1f2
|
||||
md, 0x1f1f2,0x1f1e9
|
||||
mc, 0x1f1f2,0x1f1e8
|
||||
mn, 0x1f1f2,0x1f1f3
|
||||
me, 0x1f1f2,0x1f1ea
|
||||
ms, 0x1f1f2,0x1f1f8
|
||||
ma, 0x1f1f2,0x1f1e6
|
||||
mz, 0x1f1f2,0x1f1ff
|
||||
mm, 0x1f1f2,0x1f1f2
|
||||
na, 0x1f1f3,0x1f1e6
|
||||
nr, 0x1f1f3,0x1f1f7
|
||||
np, 0x1f1f3,0x1f1f5
|
||||
nl, 0x1f1f3,0x1f1f1
|
||||
nc, 0x1f1f3,0x1f1e8
|
||||
nz, 0x1f1f3,0x1f1ff
|
||||
ni, 0x1f1f3,0x1f1ee
|
||||
ne, 0x1f1f3,0x1f1ea
|
||||
ng, 0x1f1f3,0x1f1ec
|
||||
nu, 0x1f1f3,0x1f1fa
|
||||
nf, 0x1f1f3,0x1f1eb
|
||||
kp, 0x1f1f0,0x1f1f5
|
||||
mp, 0x1f1f2,0x1f1f5
|
||||
no, 0x1f1f3,0x1f1f4
|
||||
om, 0x1f1f4,0x1f1f2
|
||||
pk, 0x1f1f5,0x1f1f0
|
||||
pw, 0x1f1f5,0x1f1fc
|
||||
ps, 0x1f1f5,0x1f1f8
|
||||
pa, 0x1f1f5,0x1f1e6
|
||||
pg, 0x1f1f5,0x1f1ec
|
||||
py, 0x1f1f5,0x1f1fe
|
||||
pe, 0x1f1f5,0x1f1ea
|
||||
ph, 0x1f1f5,0x1f1ed
|
||||
pn, 0x1f1f5,0x1f1f3
|
||||
pl, 0x1f1f5,0x1f1f1
|
||||
pt, 0x1f1f5,0x1f1f9
|
||||
pr, 0x1f1f5,0x1f1f7
|
||||
qa, 0x1f1f6,0x1f1e6
|
||||
re, 0x1f1f7,0x1f1ea
|
||||
ro, 0x1f1f7,0x1f1f4
|
||||
ru, 0x1f1f7,0x1f1fa
|
||||
rw, 0x1f1f7,0x1f1fc
|
||||
ws, 0x1f1fc,0x1f1f8
|
||||
sm, 0x1f1f8,0x1f1f2
|
||||
st, 0x1f1f8,0x1f1f9
|
||||
sa, 0x1f1f8,0x1f1e6
|
||||
sn, 0x1f1f8,0x1f1f3
|
||||
rs, 0x1f1f7,0x1f1f8
|
||||
sc, 0x1f1f8,0x1f1e8
|
||||
sl, 0x1f1f8,0x1f1f1
|
||||
sg, 0x1f1f8,0x1f1ec
|
||||
sx, 0x1f1f8,0x1f1fd
|
||||
sk, 0x1f1f8,0x1f1f0
|
||||
si, 0x1f1f8,0x1f1ee
|
||||
gs, 0x1f1ec,0x1f1f8
|
||||
sb, 0x1f1f8,0x1f1e7
|
||||
so, 0x1f1f8,0x1f1f4
|
||||
za, 0x1f1ff,0x1f1e6
|
||||
kr, 0x1f1f0,0x1f1f7
|
||||
ss, 0x1f1f8,0x1f1f8
|
||||
es, 0x1f1ea,0x1f1f8
|
||||
lk, 0x1f1f1,0x1f1f0
|
||||
bl, 0x1f1e7,0x1f1f1
|
||||
sh, 0x1f1f8,0x1f1ed
|
||||
kn, 0x1f1f0,0x1f1f3
|
||||
lc, 0x1f1f1,0x1f1e8
|
||||
pm, 0x1f1f5,0x1f1f2
|
||||
vc, 0x1f1fb,0x1f1e8
|
||||
sd, 0x1f1f8,0x1f1e9
|
||||
sr, 0x1f1f8,0x1f1f7
|
||||
sz, 0x1f1f8,0x1f1ff
|
||||
se, 0x1f1f8,0x1f1ea
|
||||
ch, 0x1f1e8,0x1f1ed
|
||||
sy, 0x1f1f8,0x1f1fe
|
||||
tw, 0x1f1f9,0x1f1fc
|
||||
tj, 0x1f1f9,0x1f1ef
|
||||
tz, 0x1f1f9,0x1f1ff
|
||||
th, 0x1f1f9,0x1f1ed
|
||||
tl, 0x1f1f9,0x1f1f1
|
||||
tg, 0x1f1f9,0x1f1ec
|
||||
tk, 0x1f1f9,0x1f1f0
|
||||
to, 0x1f1f9,0x1f1f4
|
||||
tt, 0x1f1f9,0x1f1f9
|
||||
tn, 0x1f1f9,0x1f1f3
|
||||
tr, 0x1f1f9,0x1f1f7
|
||||
tm, 0x1f1f9,0x1f1f2
|
||||
tc, 0x1f1f9,0x1f1e8
|
||||
tv, 0x1f1f9,0x1f1fb
|
||||
vi, 0x1f1fb,0x1f1ee
|
||||
ug, 0x1f1fa,0x1f1ec
|
||||
ua, 0x1f1fa,0x1f1e6
|
||||
ae, 0x1f1e6,0x1f1ea
|
||||
us, 0x1f1fa,0x1f1f8
|
||||
uy, 0x1f1fa,0x1f1fe
|
||||
uz, 0x1f1fa,0x1f1ff
|
||||
vu, 0x1f1fb,0x1f1fa
|
||||
va, 0x1f1fb,0x1f1e6
|
||||
ve, 0x1f1fb,0x1f1ea
|
||||
vn, 0x1f1fb,0x1f1f3
|
||||
wf, 0x1f1fc,0x1f1eb
|
||||
eh, 0x1f1ea,0x1f1ed
|
||||
ye, 0x1f1fe,0x1f1ea
|
||||
zm, 0x1f1ff,0x1f1f2
|
||||
zw, 0x1f1ff,0x1f1fc
|
||||
ac, 0x1f1e6,0x1f1e8
|
||||
ta, 0x1f1f9,0x1f1e6
|
||||
bv, 0x1f1e7,0x1f1fb
|
||||
hm, 0x1f1ed,0x1f1f2
|
||||
sj, 0x1f1f8,0x1f1ef
|
||||
um, 0x1f1fa,0x1f1f2
|
||||
ea, 0x1f1ea,0x1f1e6
|
||||
cp, 0x1f1e8,0x1f1f5
|
||||
dg, 0x1f1e9,0x1f1ec
|
||||
dz, 0x1f1e9,0x1f1ff
|
||||
mf, 0x1f1f2,0x1f1eb
|
Can't render this file because it has a wrong number of fields in line 168.
|
|
@ -23,23 +23,27 @@ import android.os.AsyncTask;
|
|||
import android.os.Bundle;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveDeveloperAccountsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveRelationshipAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveRemoteAccountsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
import fr.gouv.etalab.mastodon.drawers.AccountSearchDevAdapter;
|
||||
import fr.gouv.etalab.mastodon.helper.ExpandableHeightListView;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRelationshipInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRemoteAccountInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearchDevelopersAccountshInterface;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
|
||||
|
@ -48,9 +52,12 @@ import mastodon.etalab.gouv.fr.mastodon.R;
|
|||
* About activity
|
||||
*/
|
||||
|
||||
public class AboutActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface {
|
||||
public class AboutActivity extends AppCompatActivity implements OnRetrieveRemoteAccountInterface, OnRetrieveSearchDevelopersAccountshInterface, OnRetrieveRelationshipInterface {
|
||||
|
||||
private Button about_developer;
|
||||
private List<Account> developers = new ArrayList<>();
|
||||
private List<Account> contributors = new ArrayList<>();
|
||||
private AccountSearchDevAdapter accountSearchWebAdapterDeveloper;
|
||||
private AccountSearchDevAdapter accountSearchWebAdapterContributors;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
|
@ -73,7 +80,8 @@ public class AboutActivity extends AppCompatActivity implements OnRetrieveSearcA
|
|||
about_version.setText(getResources().getString(R.string.about_vesrion, version));
|
||||
} catch (PackageManager.NameNotFoundException ignored) {}
|
||||
|
||||
about_developer = (Button) findViewById(R.id.about_developer);
|
||||
ExpandableHeightListView lv_developers = (ExpandableHeightListView) findViewById(R.id.lv_developers);
|
||||
ExpandableHeightListView lv_contributors = (ExpandableHeightListView) findViewById(R.id.lv_contributors);
|
||||
Button about_code = (Button) findViewById(R.id.about_code);
|
||||
Button about_license = (Button) findViewById(R.id.about_license);
|
||||
Button about_thekinrar = (Button) findViewById(R.id.about_thekinrar);
|
||||
|
@ -93,17 +101,7 @@ public class AboutActivity extends AppCompatActivity implements OnRetrieveSearcA
|
|||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
if(Helper.isLoggedIn(getApplicationContext())) {
|
||||
about_developer.setEnabled(false);
|
||||
new RetrieveDeveloperAccountsAsyncTask(getApplicationContext(),AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
about_developer.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://mastodon.etalab.gouv.fr/@tschneider"));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
about_license.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@ -120,32 +118,21 @@ public class AboutActivity extends AppCompatActivity implements OnRetrieveSearcA
|
|||
}
|
||||
});
|
||||
|
||||
TextView about_thanks = (TextView) findViewById(R.id.about_thanks_dev);
|
||||
String currentText = about_thanks.getText().toString();
|
||||
SpannableString spanned_thanks = new SpannableString(currentText);
|
||||
int startPosition = spanned_thanks.toString().indexOf("@PhotonQyv");
|
||||
int endPosition = startPosition + "@PhotonQyv".length();
|
||||
spanned_thanks.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View textView) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://mastodon.xyz/@PhotonQyv"));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
@Override
|
||||
public void updateDrawState(TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
}
|
||||
}, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
about_thanks.setText(spanned_thanks, TextView.BufferType.SPANNABLE);
|
||||
about_thanks.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
if( theme == Helper.THEME_LIGHT) {
|
||||
about_developer.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
|
||||
about_code.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
|
||||
about_thekinrar.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
|
||||
about_translation.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
|
||||
about_license.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
|
||||
}
|
||||
|
||||
lv_contributors.setExpanded(true);
|
||||
lv_developers.setExpanded(true);
|
||||
accountSearchWebAdapterContributors = new AccountSearchDevAdapter(AboutActivity.this, contributors);
|
||||
lv_contributors.setAdapter(accountSearchWebAdapterContributors);
|
||||
accountSearchWebAdapterDeveloper = new AccountSearchDevAdapter(AboutActivity.this, developers);
|
||||
lv_developers.setAdapter(accountSearchWebAdapterDeveloper);
|
||||
new RetrieveDeveloperAccountsAsyncTask(getApplicationContext(), AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,22 +147,116 @@ public class AboutActivity extends AppCompatActivity implements OnRetrieveSearcA
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveSearchAccounts(APIResponse apiResponse) {
|
||||
about_developer.setEnabled(true);
|
||||
final List<Account> accounts = apiResponse.getAccounts();
|
||||
if( accounts != null && accounts.size() > 0 && accounts.get(0) != null) {
|
||||
about_developer.setOnClickListener(null);
|
||||
about_developer.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(AboutActivity.this, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", accounts.get(0).getId());
|
||||
intent.putExtras(b);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
public void onRetrieveRemoteAccount(boolean error, String name, String username, String instance_name, boolean locked, String avatar, String bio, String statusCount, String followingCount, String followersCount) {
|
||||
if( error){
|
||||
return;
|
||||
}
|
||||
Account account = new Account();
|
||||
account.setInstance(instance_name);
|
||||
account.setAcct(username + "@" + instance_name);
|
||||
account.setAvatar(avatar);
|
||||
account.setDisplay_name(username);
|
||||
account.setStatuses_count_str(statusCount);
|
||||
account.setFollowers_count_str(followersCount);
|
||||
account.setFollowing_count_str(followingCount);
|
||||
account.setUsername(name);
|
||||
account.setLocked(locked);
|
||||
account.setNote(bio);
|
||||
account.setFollowing(false);
|
||||
account.setRemote(true);
|
||||
|
||||
if( username.equals("@tschneider")) {
|
||||
developers.add(account);
|
||||
accountSearchWebAdapterDeveloper.notifyDataSetChanged();
|
||||
}else {
|
||||
contributors.add(account);
|
||||
accountSearchWebAdapterContributors.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveSearchDevelopersAccounts(ArrayList<Account> accounts) {
|
||||
if( accounts == null || accounts.size() == 0) {
|
||||
new RetrieveRemoteAccountsAsyncTask("tschneider", "mastodon.etalab.gouv.fr", AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new RetrieveRemoteAccountsAsyncTask("PhotonQyv", "mastodon.xyz", AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new RetrieveRemoteAccountsAsyncTask("angrytux", "social.tchncs.de", AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
return;
|
||||
}
|
||||
boolean tschneider = false;
|
||||
boolean PhotonQyv = false;
|
||||
boolean angrytux = false;
|
||||
|
||||
for(Account account: accounts){
|
||||
if( account.getUsername().equals("tschneider")){
|
||||
account.setFollowing(false);
|
||||
account.setRemote(false);
|
||||
developers.add(account);
|
||||
accountSearchWebAdapterDeveloper.notifyDataSetChanged();
|
||||
tschneider = true;
|
||||
new RetrieveRelationshipAsyncTask(getApplicationContext(), account.getId(),AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
if( account.getUsername().equals("PhotonQyv")){
|
||||
account.setFollowing(false);
|
||||
account.setRemote(false);
|
||||
contributors.add(account);
|
||||
accountSearchWebAdapterContributors.notifyDataSetChanged();
|
||||
PhotonQyv = true;
|
||||
new RetrieveRelationshipAsyncTask(getApplicationContext(), account.getId(),AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
if( account.getUsername().equals("angrytux")){
|
||||
account.setFollowing(false);
|
||||
account.setRemote(false);
|
||||
contributors.add(account);
|
||||
accountSearchWebAdapterContributors.notifyDataSetChanged();
|
||||
angrytux = true;
|
||||
new RetrieveRelationshipAsyncTask(getApplicationContext(), account.getId(),AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
if( !tschneider)
|
||||
new RetrieveRemoteAccountsAsyncTask("tschneider", "mastodon.etalab.gouv.fr", AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if( !PhotonQyv)
|
||||
new RetrieveRemoteAccountsAsyncTask("PhotonQyv", "mastodon.xyz", AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if( !angrytux)
|
||||
new RetrieveRemoteAccountsAsyncTask("angrytux", "social.tchncs.de", AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
if( developers != null && developers.size() > 0){
|
||||
for(Account account: developers){
|
||||
new RetrieveRelationshipAsyncTask(getApplicationContext(), account.getId(),AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
if( contributors != null && contributors.size() > 0){
|
||||
for(Account account: contributors){
|
||||
new RetrieveRelationshipAsyncTask(getApplicationContext(), account.getId(),AboutActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onRetrieveRelationship(Relationship relationship, Error error) {
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, "");
|
||||
if( error != null){
|
||||
return;
|
||||
}
|
||||
for( int i = 0 ; i < developers.size() ; i++){
|
||||
if( contributors.get(i).getId() != null && developers.get(i).getId().equals(relationship.getId())){
|
||||
developers.get(i).setFollowing(relationship.isFollowing() || userId.trim().equals(relationship.getId()));
|
||||
accountSearchWebAdapterDeveloper.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( int i = 0 ; i < contributors.size() ; i++){
|
||||
if( contributors.get(i).getId() != null && contributors.get(i).getId().equals(relationship.getId())){
|
||||
contributors.get(i).setFollowing(relationship.isFollowing() || userId.trim().equals(relationship.getId()));
|
||||
accountSearchWebAdapterContributors.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
package fr.gouv.etalab.mastodon.fragments;
|
||||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
|
@ -13,25 +12,32 @@ 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>. */
|
||||
package fr.gouv.etalab.mastodon.activities;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Base64;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
@ -40,35 +46,43 @@ import android.widget.ImageView;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateCredentialAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAccountInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnUpdateCredentialInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 04/06/2017.
|
||||
* Fragment for profile settings
|
||||
* Created by Thomas on 27/08/2017.
|
||||
* Edit profile activity
|
||||
*/
|
||||
public class SettingsProfileFragment extends Fragment implements OnRetrieveAccountInterface, OnUpdateCredentialInterface {
|
||||
|
||||
public class EditProfileActivity extends AppCompatActivity implements OnRetrieveAccountInterface, OnUpdateCredentialInterface {
|
||||
|
||||
|
||||
|
||||
private Context context;
|
||||
private EditText set_profile_name, set_profile_description;
|
||||
private ImageView set_profile_picture, set_header_picture;
|
||||
private Button set_change_profile_picture, set_change_header_picture, set_profile_save;
|
||||
|
@ -79,59 +93,128 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
private static final int PICK_IMAGE_PROFILE = 6545;
|
||||
private String profile_picture, header_picture, profile_username, profile_note;
|
||||
private Bitmap profile_picture_bmp, profile_header_bmp;
|
||||
private TextView title;
|
||||
private ImageView pp_actionBar;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
View rootView = inflater.inflate(R.layout.fragment_settings_profile, container, false);
|
||||
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);
|
||||
}else {
|
||||
setTheme(R.style.AppThemeDark);
|
||||
}
|
||||
setContentView(R.layout.activity_edit_profile);
|
||||
|
||||
set_profile_name = (EditText) rootView.findViewById(R.id.set_profile_name);
|
||||
set_profile_description = (EditText) rootView.findViewById(R.id.set_profile_description);
|
||||
set_profile_picture = (ImageView) rootView.findViewById(R.id.set_profile_picture);
|
||||
set_header_picture = (ImageView) rootView.findViewById(R.id.set_header_picture);
|
||||
set_change_profile_picture = (Button) rootView.findViewById(R.id.set_change_profile_picture);
|
||||
set_change_header_picture = (Button) rootView.findViewById(R.id.set_change_header_picture);
|
||||
set_profile_save = (Button) rootView.findViewById(R.id.set_profile_save);
|
||||
set_header_picture_overlay = (TextView) rootView.findViewById(R.id.set_header_picture_overlay);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if( actionBar != null) {
|
||||
LayoutInflater inflater = (LayoutInflater) this.getSystemService(android.content.Context.LAYOUT_INFLATER_SERVICE);
|
||||
View view = inflater.inflate(R.layout.conversation_action_bar, null);
|
||||
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
|
||||
title = (TextView) actionBar.getCustomView().findViewById(R.id.toolbar_title);
|
||||
pp_actionBar = (ImageView) actionBar.getCustomView().findViewById(R.id.pp_actionBar);
|
||||
title.setText(R.string.settings_title_profile);
|
||||
ImageView close_conversation = (ImageView) actionBar.getCustomView().findViewById(R.id.close_conversation);
|
||||
if( close_conversation != null){
|
||||
close_conversation.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}else{
|
||||
setTitle(R.string.settings_title_profile);
|
||||
}
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Account account = new AccountDAO(getApplicationContext(),db).getAccountByID(userId);
|
||||
String url = account.getAvatar();
|
||||
if( url.startsWith("/") ){
|
||||
url = "https://" + Helper.getLiveInstance(getApplicationContext()) + account.getAvatar();
|
||||
}
|
||||
ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
File cacheDir = new File(getCacheDir(), getString(R.string.app_name));
|
||||
ImageLoaderConfiguration configImg = new ImageLoaderConfiguration.Builder(this)
|
||||
.imageDownloader(new PatchBaseImageDownloader(getApplicationContext()))
|
||||
.threadPoolSize(5)
|
||||
.threadPriority(Thread.MIN_PRIORITY + 3)
|
||||
.denyCacheImageMultipleSizesInMemory()
|
||||
.diskCache(new UnlimitedDiskCache(cacheDir))
|
||||
.build();
|
||||
|
||||
this.imageLoader = ImageLoader.getInstance();
|
||||
this.options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||
|
||||
imageLoader.init(configImg);
|
||||
DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||
imageLoader.loadImage(url, options, new SimpleImageLoadingListener(){
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||
super.onLoadingComplete(imageUri, view, loadedImage);
|
||||
BitmapDrawable ppDrawable = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(loadedImage, (int) Helper.convertDpToPixel(25, getApplicationContext()), (int) Helper.convertDpToPixel(25, getApplicationContext()), true));
|
||||
if( pp_actionBar != null){
|
||||
pp_actionBar.setImageDrawable(ppDrawable);
|
||||
} else if( getSupportActionBar() != null){
|
||||
|
||||
getSupportActionBar().setIcon(ppDrawable);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){
|
||||
|
||||
}});
|
||||
|
||||
set_profile_name = (EditText) findViewById(R.id.set_profile_name);
|
||||
set_profile_description = (EditText) findViewById(R.id.set_profile_description);
|
||||
set_profile_picture = (ImageView) findViewById(R.id.set_profile_picture);
|
||||
set_header_picture = (ImageView) findViewById(R.id.set_header_picture);
|
||||
set_change_profile_picture = (Button) findViewById(R.id.set_change_profile_picture);
|
||||
set_change_header_picture = (Button) findViewById(R.id.set_change_header_picture);
|
||||
set_profile_save = (Button) findViewById(R.id.set_profile_save);
|
||||
set_header_picture_overlay = (TextView) findViewById(R.id.set_header_picture_overlay);
|
||||
|
||||
set_profile_save.setEnabled(false);
|
||||
set_change_header_picture.setEnabled(false);
|
||||
set_change_profile_picture.setEnabled(false);
|
||||
set_profile_name.setEnabled(false);
|
||||
set_profile_description.setEnabled(false);
|
||||
context = getContext();
|
||||
imageLoader = ImageLoader.getInstance();
|
||||
options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||
new RetrieveAccountInfoAsyncTask(context, SettingsProfileFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
|
||||
new RetrieveAccountInfoAsyncTask(getApplicationContext(), EditProfileActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if( theme == Helper.THEME_LIGHT) {
|
||||
set_profile_save.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
set_profile_save.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
|
||||
}
|
||||
return rootView;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle saveInstance) {
|
||||
super.onCreate(saveInstance);
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
this.context = context;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveAccount(Account account, Error error) {
|
||||
if( error != null ){
|
||||
Toast.makeText(context,R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
set_profile_name.setText(account.getDisplay_name());
|
||||
|
@ -161,7 +244,7 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
String content = s.toString().substring(0,160);
|
||||
set_profile_description.setText(content);
|
||||
set_profile_description.setSelection(set_profile_description.getText().length());
|
||||
Toast.makeText(context,R.string.note_no_space,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.note_no_space,Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -177,7 +260,7 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
String content = s.toString().substring(0,30);
|
||||
set_profile_name.setText(content);
|
||||
set_profile_name.setSelection(set_profile_name.getText().length());
|
||||
Toast.makeText(context,R.string.username_no_space,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.username_no_space,Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -233,9 +316,9 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
else
|
||||
profile_note = null;
|
||||
|
||||
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
|
||||
LayoutInflater inflater = ((MainActivity) context).getLayoutInflater();
|
||||
View dialogView = inflater.inflate(R.layout.dialog_profile, null);
|
||||
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(EditProfileActivity.this);
|
||||
LayoutInflater inflater = EditProfileActivity.this.getLayoutInflater();
|
||||
@SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.dialog_profile, null);
|
||||
dialogBuilder.setView(dialogView);
|
||||
|
||||
ImageView back_ground_image = (ImageView) dialogView.findViewById(R.id.back_ground_image);
|
||||
|
@ -248,7 +331,7 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
if( profile_note != null)
|
||||
dialog_profile_description.setText(profile_note);
|
||||
if( profile_header_bmp != null) {
|
||||
BitmapDrawable background = new BitmapDrawable(context.getResources(), profile_header_bmp);
|
||||
BitmapDrawable background = new BitmapDrawable(getApplicationContext().getResources(), profile_header_bmp);
|
||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
//noinspection deprecation
|
||||
back_ground_image.setBackgroundDrawable(background);
|
||||
|
@ -264,7 +347,7 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
}
|
||||
}
|
||||
if( profile_picture_bmp != null) {
|
||||
BitmapDrawable background = new BitmapDrawable(context.getResources(), profile_picture_bmp);
|
||||
BitmapDrawable background = new BitmapDrawable(getApplicationContext().getResources(), profile_picture_bmp);
|
||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
//noinspection deprecation
|
||||
dialog_profile_picture.setBackgroundDrawable(background);
|
||||
|
@ -283,7 +366,7 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
set_profile_save.setEnabled(false);
|
||||
new UpdateCredentialAsyncTask(context, profile_username, profile_note, profile_picture, header_picture, SettingsProfileFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new UpdateCredentialAsyncTask(getApplicationContext(), profile_username, profile_note, profile_picture, header_picture, EditProfileActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
dialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
|
@ -305,16 +388,16 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == PICK_IMAGE_HEADER && resultCode == Activity.RESULT_OK) {
|
||||
if (data == null) {
|
||||
Toast.makeText(context,R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
InputStream inputStream = context.getContentResolver().openInputStream(data.getData());
|
||||
InputStream inputStream = getApplicationContext().getContentResolver().openInputStream(data.getData());
|
||||
BufferedInputStream bufferedInputStream;
|
||||
if (inputStream != null) {
|
||||
bufferedInputStream = new BufferedInputStream(inputStream);
|
||||
}else {
|
||||
Toast.makeText(context,R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream);
|
||||
|
@ -326,21 +409,21 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
header_picture = "data:image/png;base64, " + Base64.encodeToString(byteArray, Base64.DEFAULT);
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(context,R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}else if(requestCode == PICK_IMAGE_PROFILE && resultCode == Activity.RESULT_OK) {
|
||||
if (data == null) {
|
||||
Toast.makeText(context,R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
InputStream inputStream = context.getContentResolver().openInputStream(data.getData());
|
||||
InputStream inputStream = getApplicationContext().getContentResolver().openInputStream(data.getData());
|
||||
BufferedInputStream bufferedInputStream;
|
||||
if (inputStream != null) {
|
||||
bufferedInputStream = new BufferedInputStream(inputStream);
|
||||
}else {
|
||||
Toast.makeText(context,R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream);
|
||||
|
@ -351,7 +434,7 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
byte[] byteArray = byteArrayOutputStream .toByteArray();
|
||||
profile_picture = "data:image/png;base64, " + Base64.encodeToString(byteArray, Base64.DEFAULT);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(context,R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -360,10 +443,11 @@ public class SettingsProfileFragment extends Fragment implements OnRetrieveAccou
|
|||
@Override
|
||||
public void onUpdateCredential(APIResponse apiResponse) {
|
||||
if( apiResponse.getError() != null){
|
||||
Toast.makeText(context, R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
Toast.makeText(context, R.string.toast_update_credential_ok, Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_update_credential_ok, Toast.LENGTH_LONG).show();
|
||||
set_profile_save.setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -362,6 +362,8 @@ public class MediaActivity extends AppCompatActivity {
|
|||
@Override
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
loader.setVisibility(View.GONE);
|
||||
mp.start();
|
||||
mp.setLooping(true);
|
||||
}
|
||||
});
|
||||
videoView.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -261,7 +261,7 @@ public class RemoteFollowActivity extends AppCompatActivity implements OnRetriev
|
|||
|
||||
|
||||
@Override
|
||||
public void onRetrieveRemoteAccount(boolean error, String name, String username, boolean locked, String avatar, String bio, int statusCount, int followingCount, int followersCount) {
|
||||
public void onRetrieveRemoteAccount(boolean error, String name, String username, String instance_name, boolean locked, String avatar, String bio, String statusCount, String followingCount, String followersCount) {
|
||||
loader.setVisibility(View.GONE);
|
||||
rf_search.setEnabled(true);
|
||||
if( error){
|
||||
|
@ -274,9 +274,9 @@ public class RemoteFollowActivity extends AppCompatActivity implements OnRetriev
|
|||
account.setAcct(screen_name + "@" + instance_name);
|
||||
account.setAvatar(avatar);
|
||||
account.setDisplay_name(username);
|
||||
account.setStatuses_count(statusCount);
|
||||
account.setFollowers_count(followersCount);
|
||||
account.setFollowing_count(followingCount);
|
||||
account.setStatuses_count_str(statusCount);
|
||||
account.setFollowers_count_str(followersCount);
|
||||
account.setFollowing_count_str(followingCount);
|
||||
account.setUsername(name);
|
||||
account.setLocked(locked);
|
||||
account.setNote(bio);
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
|
@ -89,6 +90,8 @@ import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
|||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAccountInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsAccountInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRelationshipInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
|
||||
|
@ -122,6 +125,7 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
|||
private BroadcastReceiver hide_header;
|
||||
private boolean isHiddingShowing = false;
|
||||
private LinearLayout main_header_container;
|
||||
private ImageView header_edit_profile;
|
||||
|
||||
public enum action{
|
||||
FOLLOW,
|
||||
|
@ -149,6 +153,7 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
|||
account_follow = (FloatingActionButton) findViewById(R.id.account_follow);
|
||||
account_follow_request = (TextView) findViewById(R.id.account_follow_request);
|
||||
main_header_container = (LinearLayout) findViewById(R.id.main_header_container);
|
||||
header_edit_profile = (ImageView) findViewById(R.id.header_edit_profile);
|
||||
account_follow.setEnabled(false);
|
||||
if(b != null){
|
||||
accountId = b.getString("accountId");
|
||||
|
@ -298,6 +303,14 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
|||
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(hide_header, new IntentFilter(Helper.HEADER_ACCOUNT + String.valueOf(instanceValue)));
|
||||
}
|
||||
|
||||
header_edit_profile.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(ShowAccountActivity.this, EditProfileActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -520,6 +533,7 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
|
|||
account_follow.setEnabled(true);
|
||||
if( accountId != null && accountId.equals(userId)){
|
||||
account_follow.setVisibility(View.GONE);
|
||||
header_edit_profile.setVisibility(View.VISIBLE);
|
||||
}else if( relationship.isBlocking()){
|
||||
account_follow.setImageResource(R.drawable.ic_unlock_alt);
|
||||
doAction = action.UNBLOCK;
|
||||
|
|
|
@ -17,11 +17,14 @@ package fr.gouv.etalab.mastodon.activities;
|
|||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
|
@ -49,6 +52,7 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.webkit.URLUtil;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
|
@ -66,6 +70,8 @@ import android.widget.TextView;
|
|||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.loopj.android.http.AsyncHttpClient;
|
||||
import com.loopj.android.http.BinaryHttpResponseHandler;
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
@ -74,9 +80,13 @@ import com.nostra13.universalimageloader.core.assist.FailReason;
|
|||
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -86,6 +96,7 @@ import java.util.Locale;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import cz.msebera.android.httpclient.Header;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostStatusAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAccountsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UploadActionAsyncTask;
|
||||
|
@ -136,7 +147,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
private EditText toot_cw_content;
|
||||
private LinearLayout toot_reply_content_container;
|
||||
private Status tootReply = null;
|
||||
private String sharedContent, sharedSubject;
|
||||
private String sharedContent, sharedSubject, sharedContentIni;
|
||||
private CheckBox toot_sensitive;
|
||||
public long currentToId;
|
||||
private long restored;
|
||||
|
@ -148,7 +159,9 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
private HorizontalScrollView picture_scrollview;
|
||||
private int currentCursorPosition, searchLength;
|
||||
private TextView toot_space_left;
|
||||
private String initialContent;
|
||||
private final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754;
|
||||
private BroadcastReceiver receive_picture;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -240,6 +253,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
if(b != null) {
|
||||
tootReply = b.getParcelable("tootReply");
|
||||
sharedContent = b.getString("sharedContent", null);
|
||||
sharedContentIni = b.getString("sharedContent", null);
|
||||
sharedSubject = b.getString("sharedSubject", null);
|
||||
// ACTION_SEND route
|
||||
if (b.getInt("uriNumber", 0) == 1) {
|
||||
|
@ -261,6 +275,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}
|
||||
restored = b.getLong("restored", -1);
|
||||
}
|
||||
initialContent = toot_content.getText().toString();
|
||||
if( restored != -1 ){
|
||||
toot_it.setVisibility(View.GONE);
|
||||
invalidateOptionsMenu();
|
||||
|
@ -299,21 +314,75 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}});
|
||||
|
||||
if( sharedContent != null ){ //Shared content
|
||||
|
||||
if( sharedSubject != null){
|
||||
sharedContent = sharedSubject + "\n\n" + sharedContent;
|
||||
}
|
||||
receive_picture = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String image = intent.getStringExtra("image");
|
||||
String title = intent.getStringExtra("title");
|
||||
String description = intent.getStringExtra("description");
|
||||
if( description != null && description.length() > 20 ){
|
||||
if( description.length() > 200 )
|
||||
description = description.substring(0,199) + "…";
|
||||
if( title != null)
|
||||
sharedContent = title + "\n\n" + description + "\n\n" + sharedContentIni;
|
||||
else
|
||||
sharedContent = description + "\n\n" + sharedContentIni;
|
||||
toot_content.setText(sharedContent);
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
toot_content.setSelection(toot_content.getText().length());
|
||||
}
|
||||
if( image != null){
|
||||
AsyncHttpClient client = new AsyncHttpClient();
|
||||
String[] allowedTypes = new String[] { "image/png","image/jpeg" };
|
||||
client.get(image, new BinaryHttpResponseHandler(allowedTypes) {
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) {
|
||||
OutputStream f;
|
||||
try {
|
||||
f = new FileOutputStream(getCacheDir() + URLUtil.guessFileName(image, null, null));
|
||||
picture_scrollview.setVisibility(View.VISIBLE);
|
||||
InputStream bis = new ByteArrayInputStream(binaryData);
|
||||
loading_picture.setVisibility(View.VISIBLE);
|
||||
toot_picture.setEnabled(false);
|
||||
new UploadActionAsyncTask(getApplicationContext(),bis,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
f.write(binaryData);
|
||||
f.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(receive_picture, new IntentFilter(Helper.RECEIVE_PICTURE));
|
||||
toot_content.setText( String.format("\n%s", sharedContent));
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
}
|
||||
attachments = new ArrayList<>();
|
||||
int charsInCw = 0;
|
||||
int charsInToot = 0;
|
||||
|
||||
uploadSharedImage(sharedUri);
|
||||
if (!sharedUri.isEmpty()) {
|
||||
uploadSharedImage(sharedUri);
|
||||
}
|
||||
|
||||
boolean isAccountPrivate = account.isLocked();
|
||||
if(isAccountPrivate){
|
||||
if( tootReply == null) {
|
||||
visibility = "private";
|
||||
toot_visibility.setImageResource(R.drawable.ic_action_lock_closed);
|
||||
}else {
|
||||
if( visibility.equals("direct") ){
|
||||
toot_visibility.setImageResource(R.drawable.ic_local_post_office);
|
||||
|
@ -523,6 +592,14 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(){
|
||||
super.onDestroy();
|
||||
if( receive_picture != null)
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_picture);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
@NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
|
@ -546,6 +623,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
mToast.show();
|
||||
}
|
||||
|
||||
|
||||
// Handles uploading shared images
|
||||
public void uploadSharedImage(ArrayList<Uri> uri)
|
||||
{
|
||||
|
@ -769,6 +847,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
//Clear content
|
||||
toot_content.setText("");
|
||||
toot_cw_content.setText("");
|
||||
toot_space_left.setText(0);
|
||||
if( attachments != null) {
|
||||
for (Attachment attachment : attachments) {
|
||||
View namebar = findViewById(Integer.parseInt(attachment.getId()));
|
||||
|
@ -842,6 +921,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
//Adds the shorter text_url of attachment at the end of the toot
|
||||
int selectionBefore = toot_content.getSelectionStart();
|
||||
toot_content.setText(toot_content.getText().toString() + "\n" + attachment.getText_url());
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
//Moves the cursor
|
||||
if (selectionBefore >= 0)
|
||||
toot_content.setSelection(selectionBefore);
|
||||
|
@ -890,6 +970,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
//Clears the text_url at the end of the toot
for this attachment
|
||||
int selectionBefore = toot_content.getSelectionStart();
|
||||
toot_content.setText(toot_content.getText().toString().replace(attachment.getText_url(), ""));
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
//Moves the cursor
|
||||
if (selectionBefore >= 0)
|
||||
toot_content.setSelection(selectionBefore);
|
||||
|
@ -977,6 +1058,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
//Clear the toot
|
||||
toot_content.setText("");
|
||||
toot_cw_content.setText("");
|
||||
toot_space_left.setText("0");
|
||||
if( attachments != null) {
|
||||
for (Attachment attachment : attachments) {
|
||||
View namebar = findViewById(Integer.parseInt(attachment.getId()));
|
||||
|
@ -1059,6 +1141,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
if( currentCursorPosition < oldContent.length() - 1)
|
||||
newContent += oldContent.substring(currentCursorPosition, oldContent.length()-1);
|
||||
toot_content.setText(newContent);
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
toot_content.setSelection(newPosition);
|
||||
AccountsSearchAdapter accountsListAdapter = new AccountsSearchAdapter(TootActivity.this, new ArrayList<Account>());
|
||||
toot_content.setThreshold(1);
|
||||
|
@ -1132,6 +1215,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}
|
||||
String content = status.getContent();
|
||||
toot_content.setText(content);
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
toot_content.setSelection(toot_content.getText().length());
|
||||
switch (status.getVisibility()){
|
||||
case "public":
|
||||
|
@ -1163,6 +1247,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
else
|
||||
setTitle(R.string.toot_title);
|
||||
}
|
||||
initialContent = toot_content.getText().toString();
|
||||
toot_space_left.setText(String.valueOf(toot_content.getText().length() + toot_cw_content.getText().length()));
|
||||
}
|
||||
|
||||
|
@ -1245,9 +1330,10 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
//Put a "<space>dot<space>" at the end of all mentioned account to force capitalization
|
||||
toot_content.append(" . ");
|
||||
}
|
||||
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
toot_content.setSelection(toot_content.getText().length()); //Put cursor at the end
|
||||
}
|
||||
initialContent = toot_content.getText().toString();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1256,7 +1342,8 @@ 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()))
|
||||
return;
|
||||
Status toot = new Status();
|
||||
toot.setSensitive(isSensitive);
|
||||
toot.setMedia_attachments(attachments);
|
||||
|
@ -1311,6 +1398,4 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
changeDrawableColor(TootActivity.this, R.drawable.ic_check, R.color.white);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -147,6 +147,20 @@ public class WebviewActivity extends AppCompatActivity {
|
|||
this.url = newUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
if( webView != null)
|
||||
webView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
if( webView != null)
|
||||
webView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (webView.canGoBack()){
|
||||
|
@ -159,6 +173,7 @@ public class WebviewActivity extends AppCompatActivity {
|
|||
@Override
|
||||
public void onDestroy(){
|
||||
super.onDestroy();
|
||||
|
||||
if( webView != null)
|
||||
webView.destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,13 @@ package fr.gouv.etalab.mastodon.asynctasks;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearchDevelopersAccountshInterface;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -29,23 +33,32 @@ import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
|
|||
public class RetrieveDeveloperAccountsAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private Context context;
|
||||
private APIResponse apiResponse;
|
||||
private OnRetrieveSearcAccountshInterface listener;
|
||||
private OnRetrieveSearchDevelopersAccountshInterface listener;
|
||||
private ArrayList<Account> accounts;
|
||||
|
||||
public RetrieveDeveloperAccountsAsyncTask(Context context, OnRetrieveSearcAccountshInterface onRetrieveSearcAccountshInterface){
|
||||
public RetrieveDeveloperAccountsAsyncTask(Context context, OnRetrieveSearchDevelopersAccountshInterface onRetrieveSearchDevelopersAccountshInterface){
|
||||
this.context = context;
|
||||
this.listener = onRetrieveSearcAccountshInterface;
|
||||
this.listener = onRetrieveSearchDevelopersAccountshInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
API api = new API(context);
|
||||
apiResponse = api.searchDeveloper();
|
||||
accounts = new ArrayList<>();
|
||||
APIResponse apiResponse = api.searchAccounts("@tschneider@mastodon.etalab.gouv.fr", 1);
|
||||
if( apiResponse.getAccounts() != null && apiResponse.getAccounts().size() > 0)
|
||||
accounts.add(apiResponse.getAccounts().get(0));
|
||||
apiResponse = api.searchAccounts("@PhotonQyv@mastodon.xyz",1);
|
||||
if( apiResponse.getAccounts() != null && apiResponse.getAccounts().size() > 0)
|
||||
accounts.add(apiResponse.getAccounts().get(0));
|
||||
apiResponse = api.searchAccounts("@angrytux@social.tchncs.de",1);
|
||||
if( apiResponse.getAccounts() != null && apiResponse.getAccounts().size() > 0)
|
||||
accounts.add(apiResponse.getAccounts().get(0));
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrieveSearchAccounts(apiResponse);
|
||||
listener.onRetrieveSearchDevelopersAccounts(accounts);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.util.Date;
|
||||
import android.util.Log;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
|
@ -61,8 +59,6 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
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){
|
||||
|
@ -73,7 +69,6 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
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;
|
||||
|
@ -83,21 +78,11 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
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) {
|
||||
|
||||
API api = new API(context);
|
||||
switch (action){
|
||||
case HOME:
|
||||
|
@ -134,14 +119,4 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
protected void onPostExecute(Void result) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/* 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>. */
|
||||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.select.Elements;
|
||||
import java.io.IOException;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveMetaDataInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 02/09/2017.
|
||||
* Retrieves metadata of a remote page
|
||||
*/
|
||||
|
||||
public class RetrieveMetaDataAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private OnRetrieveMetaDataInterface listener;
|
||||
private String url;
|
||||
private boolean error = false;
|
||||
private String image, title, description;
|
||||
|
||||
public RetrieveMetaDataAsyncTask(String url, OnRetrieveMetaDataInterface onRetrieveRemoteAccountInterface){
|
||||
this.url = url;
|
||||
this.listener = onRetrieveRemoteAccountInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36";
|
||||
try {
|
||||
Document document = Jsoup.connect(url).userAgent(userAgent).get();
|
||||
Elements metaOgTitle = document.select("meta[property=og:title]");
|
||||
if (metaOgTitle != null) {
|
||||
title = metaOgTitle.attr("content");
|
||||
} else {
|
||||
title = document.title();
|
||||
}
|
||||
Elements metaOgDescription = document.select("meta[property=og:description]");
|
||||
if (metaOgDescription != null) {
|
||||
description = metaOgDescription.attr("content");
|
||||
} else {
|
||||
description = "";
|
||||
}
|
||||
Elements metaOgImage = document.select("meta[property=og:image]");
|
||||
if (metaOgImage != null) {
|
||||
image = metaOgImage.attr("content");
|
||||
}
|
||||
} catch (IOException | IndexOutOfBoundsException e) {
|
||||
error = true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrieveMetaData(error, image, title, description);
|
||||
}
|
||||
|
||||
}
|
|
@ -15,14 +15,9 @@
|
|||
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;
|
||||
|
||||
|
||||
|
@ -51,20 +46,8 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
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
|
||||
protected Void doInBackground(Void... params) {
|
||||
|
@ -82,10 +65,4 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,11 @@ package fr.gouv.etalab.mastodon.asynctasks;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRelationshipInterface;
|
||||
|
||||
/**
|
||||
|
@ -42,7 +44,6 @@ public class RetrieveRelationshipAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
|
||||
api = new API(context);
|
||||
relationship = api.getRelationship(accountId);
|
||||
return null;
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.select.Elements;
|
||||
import java.io.IOException;
|
||||
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRemoteAccountInterface;
|
||||
|
||||
|
||||
|
@ -32,7 +33,7 @@ public class RetrieveRemoteAccountsAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
private OnRetrieveRemoteAccountInterface listener;
|
||||
private String url;
|
||||
private String avatar, name, username, bio;
|
||||
private int statusCount, followingCount, followersCount;
|
||||
private String statusCount, followingCount, followersCount;
|
||||
private boolean islocked;
|
||||
private boolean error = false;
|
||||
private String instance;
|
||||
|
@ -56,23 +57,24 @@ public class RetrieveRemoteAccountsAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
Elements nameElement = document.getElementsByClass("name");
|
||||
name = nameElement.get(0).getElementsByClass("p-name").get(0).html();
|
||||
username = nameElement.get(0).getElementsByTag("span").get(1).html();
|
||||
islocked = nameElement.get(0).getElementsByClass("fa-lock") != null;
|
||||
islocked = (nameElement.get(0).getElementsByClass("fa-lock") != null && nameElement.get(0).getElementsByClass("fa-lock").size() > 0);
|
||||
|
||||
Elements bioElement = document.getElementsByClass("bio");
|
||||
bio = bioElement.get(0).html();
|
||||
Elements countElement = document.getElementsByClass("counter-number");
|
||||
statusCount = Integer.parseInt(countElement.get(0).html());
|
||||
followingCount = Integer.parseInt(countElement.get(1).html());
|
||||
followersCount = Integer.parseInt(countElement.get(2).html());
|
||||
} catch (IOException | IndexOutOfBoundsException e) {
|
||||
statusCount = countElement.get(0).html();
|
||||
followingCount = countElement.get(1).html();
|
||||
followersCount = countElement.get(2).html();
|
||||
} catch (Exception e) {
|
||||
error = true;
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrieveRemoteAccount(error, name, username, islocked, avatar, bio, statusCount, followingCount, followersCount);
|
||||
listener.onRetrieveRemoteAccount(error, name, username, instance, islocked, avatar, bio, statusCount, followingCount, followersCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.content.Context;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
|
@ -68,6 +69,7 @@ public class RetrieveScheduledTootsAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
}else{
|
||||
jobIds = new int[]{};
|
||||
}
|
||||
|
||||
if( storedStatuses != null && storedStatuses.size() > 0 ){
|
||||
for(StoredStatus ss: storedStatuses){
|
||||
if (!Helper.isJobPresent(jobIds, ss.getJobId())){
|
||||
|
|
|
@ -188,12 +188,12 @@ public class API {
|
|||
get("/accounts/verify_credentials", null, new JsonHttpResponseHandler() {
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
account = parseAccountResponse(response);
|
||||
account = parseAccountResponse(context, response);
|
||||
}
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
|
||||
try {
|
||||
account = parseAccountResponse(response.getJSONObject(0));
|
||||
account = parseAccountResponse(context, response.getJSONObject(0));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -217,12 +217,12 @@ public class API {
|
|||
get(String.format("/accounts/%s",accountId), null, new JsonHttpResponseHandler() {
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
account = parseAccountResponse(response);
|
||||
account = parseAccountResponse(context, response);
|
||||
}
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
|
||||
try {
|
||||
account = parseAccountResponse(response.getJSONObject(0));
|
||||
account = parseAccountResponse(context, response.getJSONObject(0));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ public class API {
|
|||
get(String.format("/accounts/%s/statuses", accountId), params, new JsonHttpResponseHandler() {
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
Status status = parseStatuses(response);
|
||||
Status status = parseStatuses(context, response);
|
||||
statuses.add(status);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -365,7 +365,7 @@ public class API {
|
|||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
Status status = parseStatuses(response);
|
||||
Status status = parseStatuses(context, response);
|
||||
statuses.add(status);
|
||||
}
|
||||
@Override
|
||||
|
@ -445,7 +445,7 @@ public class API {
|
|||
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
Status status = parseStatuses(response);
|
||||
Status status = parseStatuses(context, response);
|
||||
statuses.add(status);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -500,7 +500,7 @@ public class API {
|
|||
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
Status status = parseStatuses(response);
|
||||
Status status = parseStatuses(context, response);
|
||||
statuses.add(status);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -557,7 +557,7 @@ public class API {
|
|||
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
Status status = parseStatuses(response);
|
||||
Status status = parseStatuses(context, response);
|
||||
statuses.add(status);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -641,7 +641,7 @@ public class API {
|
|||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
Account account = parseAccountResponse(response);
|
||||
Account account = parseAccountResponse(context, response);
|
||||
accounts.add(account);
|
||||
}
|
||||
@Override
|
||||
|
@ -692,7 +692,7 @@ public class API {
|
|||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
Account account = parseAccountResponse(response);
|
||||
Account account = parseAccountResponse(context, response);
|
||||
accounts.add(account);
|
||||
}
|
||||
@Override
|
||||
|
@ -741,7 +741,7 @@ public class API {
|
|||
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
Status status = parseStatuses(response);
|
||||
Status status = parseStatuses(context, response);
|
||||
statuses.add(status);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -945,7 +945,7 @@ public class API {
|
|||
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
Status statusreturned = parseStatuses(response);
|
||||
Status statusreturned = parseStatuses(context, response);
|
||||
statuses.add(statusreturned);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -1041,7 +1041,7 @@ public class API {
|
|||
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
Notification notification = parseNotificationResponse(response);
|
||||
Notification notification = parseNotificationResponse(context, response);
|
||||
notifications.add(notification);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -1118,37 +1118,6 @@ public class API {
|
|||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Developer account when searching (ie: via @...) *synchronously*
|
||||
*
|
||||
* @return APIResponse
|
||||
*/
|
||||
public APIResponse searchDeveloper() {
|
||||
RequestParams params = new RequestParams();
|
||||
params.add("q", "tschneider");
|
||||
get("/accounts/search", params, new JsonHttpResponseHandler() {
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
accounts = new ArrayList<>();
|
||||
account = parseAccountResponse(response);
|
||||
accounts.add(account);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
}
|
||||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
|
||||
accounts = parseDeveloperResponse(response);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
}
|
||||
@Override
|
||||
public void onFailure(int statusCode, Header[] headers, Throwable error, JSONObject response){
|
||||
setError(statusCode, error);
|
||||
}
|
||||
});
|
||||
apiResponse.setAccounts(accounts);
|
||||
return apiResponse;
|
||||
}
|
||||
/**
|
||||
* Retrieves Accounts when searching (ie: via @...) *synchronously*
|
||||
*
|
||||
|
@ -1170,7 +1139,7 @@ public class API {
|
|||
@Override
|
||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||
accounts = new ArrayList<>();
|
||||
account = parseAccountResponse(response);
|
||||
account = parseAccountResponse(context, response);
|
||||
accounts.add(account);
|
||||
apiResponse.setSince_id(findSinceId(headers));
|
||||
apiResponse.setMax_id(findMaxId(headers));
|
||||
|
@ -1236,7 +1205,7 @@ public class API {
|
|||
while (i < jsonArray.length() ){
|
||||
|
||||
JSONObject resobj = jsonArray.getJSONObject(i);
|
||||
Status status = parseStatuses(resobj);
|
||||
Status status = parseStatuses(context, resobj);
|
||||
i++;
|
||||
statuses.add(status);
|
||||
}
|
||||
|
@ -1253,7 +1222,7 @@ public class API {
|
|||
* @return Status
|
||||
*/
|
||||
@SuppressWarnings("InfiniteRecursion")
|
||||
private Status parseStatuses(JSONObject resobj){
|
||||
public static Status parseStatuses(Context context, JSONObject resobj){
|
||||
Status status = new Status();
|
||||
try {
|
||||
status.setId(resobj.get("id").toString());
|
||||
|
@ -1315,14 +1284,14 @@ public class API {
|
|||
}
|
||||
status.setTags(tags);
|
||||
|
||||
status.setAccount(parseAccountResponse(resobj.getJSONObject("account")));
|
||||
status.setAccount(parseAccountResponse(context, resobj.getJSONObject("account")));
|
||||
status.setContent(resobj.get("content").toString());
|
||||
status.setFavourites_count(Integer.valueOf(resobj.get("favourites_count").toString()));
|
||||
status.setReblogs_count(Integer.valueOf(resobj.get("reblogs_count").toString()));
|
||||
status.setReblogged(Boolean.valueOf(resobj.get("reblogged").toString()));
|
||||
status.setFavourited(Boolean.valueOf(resobj.get("favourited").toString()));
|
||||
try{
|
||||
status.setReblog(parseStatuses(resobj.getJSONObject("reblog")));
|
||||
status.setReblog(parseStatuses(context, resobj.getJSONObject("reblog")));
|
||||
}catch (Exception ignored){}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -1355,7 +1324,7 @@ public class API {
|
|||
* @param resobj JSONObject
|
||||
* @return Account
|
||||
*/
|
||||
private Account parseAccountResponse(JSONObject resobj){
|
||||
private static Account parseAccountResponse(Context context, JSONObject resobj){
|
||||
|
||||
Account account = new Account();
|
||||
try {
|
||||
|
@ -1392,7 +1361,7 @@ public class API {
|
|||
int i = 0;
|
||||
while (i < jsonArray.length() ) {
|
||||
JSONObject resobj = jsonArray.getJSONObject(i);
|
||||
Account account = parseAccountResponse(resobj);
|
||||
Account account = parseAccountResponse(context, resobj);
|
||||
accounts.add(account);
|
||||
i++;
|
||||
}
|
||||
|
@ -1416,7 +1385,7 @@ public class API {
|
|||
Account account = null;
|
||||
while (i < jsonArray.length() ) {
|
||||
JSONObject resobj = jsonArray.getJSONObject(i);
|
||||
account = parseAccountResponse(resobj);
|
||||
account = parseAccountResponse(context, resobj);
|
||||
if( account.getAcct().contains(Helper.DEVELOPER_INSTANCE))
|
||||
accounts.add(account);
|
||||
i++;
|
||||
|
@ -1500,16 +1469,16 @@ public class API {
|
|||
* @param resobj JSONObject
|
||||
* @return Account
|
||||
*/
|
||||
private Notification parseNotificationResponse(JSONObject resobj){
|
||||
public static Notification parseNotificationResponse(Context context, JSONObject resobj){
|
||||
|
||||
Notification notification = new Notification();
|
||||
try {
|
||||
notification.setId(resobj.get("id").toString());
|
||||
notification.setType(resobj.get("type").toString());
|
||||
notification.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
|
||||
notification.setAccount(parseAccountResponse(resobj.getJSONObject("account")));
|
||||
notification.setAccount(parseAccountResponse(context, resobj.getJSONObject("account")));
|
||||
try{
|
||||
notification.setStatus(parseStatuses(resobj.getJSONObject("status")));
|
||||
notification.setStatus(parseStatuses(context, resobj.getJSONObject("status")));
|
||||
}catch (Exception ignored){}
|
||||
notification.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
|
||||
} catch (JSONException e) {
|
||||
|
@ -1531,7 +1500,7 @@ public class API {
|
|||
while (i < jsonArray.length() ) {
|
||||
|
||||
JSONObject resobj = jsonArray.getJSONObject(i);
|
||||
Notification notification = parseNotificationResponse(resobj);
|
||||
Notification notification = parseNotificationResponse(context, resobj);
|
||||
notifications.add(notification);
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ public class Account implements Parcelable {
|
|||
private int followers_count;
|
||||
private int following_count;
|
||||
private int statuses_count;
|
||||
private String followers_count_str;
|
||||
private String following_count_str;
|
||||
private String statuses_count_str;
|
||||
private String note;
|
||||
private String url;
|
||||
private String avatar;
|
||||
|
@ -43,6 +46,8 @@ public class Account implements Parcelable {
|
|||
private String header_static;
|
||||
private String token;
|
||||
private String instance;
|
||||
private boolean isFollowing;
|
||||
private boolean isRemote;
|
||||
|
||||
protected Account(Parcel in) {
|
||||
id = in.readString();
|
||||
|
@ -237,4 +242,44 @@ public class Account implements Parcelable {
|
|||
dest.writeString(token);
|
||||
dest.writeString(instance);
|
||||
}
|
||||
|
||||
public boolean isFollowing() {
|
||||
return isFollowing;
|
||||
}
|
||||
|
||||
public void setFollowing(boolean following) {
|
||||
isFollowing = following;
|
||||
}
|
||||
|
||||
public boolean isRemote() {
|
||||
return isRemote;
|
||||
}
|
||||
|
||||
public void setRemote(boolean remote) {
|
||||
isRemote = remote;
|
||||
}
|
||||
|
||||
public String getFollowers_count_str() {
|
||||
return followers_count_str;
|
||||
}
|
||||
|
||||
public void setFollowers_count_str(String followers_count_str) {
|
||||
this.followers_count_str = followers_count_str;
|
||||
}
|
||||
|
||||
public String getFollowing_count_str() {
|
||||
return following_count_str;
|
||||
}
|
||||
|
||||
public void setFollowing_count_str(String following_count_str) {
|
||||
this.following_count_str = following_count_str;
|
||||
}
|
||||
|
||||
public String getStatuses_count_str() {
|
||||
return statuses_count_str;
|
||||
}
|
||||
|
||||
public void setStatuses_count_str(String statuses_count_str) {
|
||||
this.statuses_count_str = statuses_count_str;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,16 @@
|
|||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 23/04/2017.
|
||||
*/
|
||||
|
||||
public class Notification {
|
||||
public class Notification implements Parcelable {
|
||||
|
||||
private String id;
|
||||
private String type;
|
||||
|
@ -29,6 +32,27 @@ public class Notification {
|
|||
private Account account;
|
||||
private Status status;
|
||||
|
||||
protected Notification(Parcel in) {
|
||||
id = in.readString();
|
||||
type = in.readString();
|
||||
account = in.readParcelable(Account.class.getClassLoader());
|
||||
status = in.readParcelable(Status.class.getClassLoader());
|
||||
}
|
||||
|
||||
public Notification(){};
|
||||
|
||||
public static final Creator<Notification> CREATOR = new Creator<Notification>() {
|
||||
@Override
|
||||
public Notification createFromParcel(Parcel in) {
|
||||
return new Notification(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] newArray(int size) {
|
||||
return new Notification[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -68,4 +92,17 @@ public class Notification {
|
|||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(id);
|
||||
dest.writeString(type);
|
||||
dest.writeParcelable(account, flags);
|
||||
dest.writeParcelable(status, flags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ public class Status implements Parcelable {
|
|||
private String language;
|
||||
private boolean isTranslated = false;
|
||||
private boolean isTranslationShown = false;
|
||||
private boolean isNew = false;
|
||||
|
||||
protected Status(Parcel in) {
|
||||
id = in.readString();
|
||||
|
@ -79,6 +80,7 @@ public class Status implements Parcelable {
|
|||
spoilerShown = in.readByte() != 0;
|
||||
isTranslated = in.readByte() != 0;
|
||||
isTranslationShown = in.readByte() != 0;
|
||||
isNew = in.readByte() != 0;
|
||||
}
|
||||
|
||||
public Status(){}
|
||||
|
@ -294,6 +296,7 @@ public class Status implements Parcelable {
|
|||
dest.writeByte((byte) (spoilerShown ? 1 : 0));
|
||||
dest.writeByte((byte) (isTranslated ? 1 : 0));
|
||||
dest.writeByte((byte) (isTranslationShown ? 1 : 0));
|
||||
dest.writeByte((byte) (isNew ? 1 : 0));
|
||||
}
|
||||
|
||||
public boolean isSpoilerShown() {
|
||||
|
@ -343,4 +346,12 @@ public class Status implements Parcelable {
|
|||
public void setReplies(List<Status> replies) {
|
||||
this.replies = replies;
|
||||
}
|
||||
|
||||
public boolean isNew() {
|
||||
return isNew;
|
||||
}
|
||||
|
||||
public void setNew(boolean aNew) {
|
||||
isNew = aNew;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package fr.gouv.etalab.mastodon.client;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 29/08/2017.
|
||||
*
|
||||
*/
|
||||
|
||||
public class TLSSocketFactory extends SSLSocketFactory {
|
||||
|
||||
private final SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
|
||||
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
|
||||
|
||||
X509TrustManager tm = new X509TrustManager() {
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
sslContext.init(null, new TrustManager[]{tm}, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDefaultCipherSuites() {
|
||||
return sslContext.getSocketFactory().getDefaultCipherSuites();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedCipherSuites() {
|
||||
return sslContext.getSocketFactory().getSupportedCipherSuites();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket() throws IOException {
|
||||
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
|
||||
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket(s, host, port, autoClose));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
|
||||
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket(host, port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
|
||||
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket(host, port, localHost, localPort));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress host, int port) throws IOException {
|
||||
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket(host, port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
|
||||
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket(address, port, localAddress, localPort));
|
||||
}
|
||||
|
||||
private Socket enableTLSOnSocket(Socket socket) {
|
||||
if(socket != null && (socket instanceof SSLSocket)) {
|
||||
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
package fr.gouv.etalab.mastodon.drawers;
|
||||
/* 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>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 03/09/2017.
|
||||
* Adapter for accounts from web
|
||||
*/
|
||||
public class AccountSearchDevAdapter extends BaseAdapter implements OnPostActionInterface {
|
||||
|
||||
private List<Account> accounts;
|
||||
private LayoutInflater layoutInflater;
|
||||
private Context context;
|
||||
private ViewHolder holder;
|
||||
|
||||
public AccountSearchDevAdapter(Context context, List<Account> accounts){
|
||||
this.context = context;
|
||||
this.accounts = accounts;
|
||||
layoutInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return accounts.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return accounts.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
|
||||
ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
File cacheDir = new File(context.getCacheDir(), context.getString(R.string.app_name));
|
||||
ImageLoaderConfiguration configImg = new ImageLoaderConfiguration.Builder(context)
|
||||
.imageDownloader(new PatchBaseImageDownloader(context))
|
||||
.threadPoolSize(5)
|
||||
.threadPriority(Thread.MIN_PRIORITY + 3)
|
||||
.denyCacheImageMultipleSizesInMemory()
|
||||
.diskCache(new UnlimitedDiskCache(cacheDir))
|
||||
.build();
|
||||
if( !imageLoader.isInited())
|
||||
imageLoader.init(configImg);
|
||||
DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||
final Account account = accounts.get(position);
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = layoutInflater.inflate(R.layout.drawer_account_search_dev, parent, false);
|
||||
holder = new ViewHolder();
|
||||
holder.account_pp = (ImageView) convertView.findViewById(R.id.account_pp);
|
||||
holder.account_dn = (TextView) convertView.findViewById(R.id.account_dn);
|
||||
holder.account_un = (TextView) convertView.findViewById(R.id.account_un);
|
||||
holder.account_follow = (FloatingActionButton) convertView.findViewById(R.id.account_follow);
|
||||
holder.acccount_container = (LinearLayout) convertView.findViewById(R.id.acccount_container);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
//Redraws icon for locked accounts
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
if( account != null && account.isLocked()){
|
||||
Drawable img = ContextCompat.getDrawable(context, R.drawable.ic_action_lock_closed);
|
||||
img.setBounds(0,0,(int) (20 * scale + 0.5f),(int) (20 * scale + 0.5f));
|
||||
holder.account_dn.setCompoundDrawables( null, null, img, null);
|
||||
}else{
|
||||
holder.account_dn.setCompoundDrawables( null, null, null, null);
|
||||
}
|
||||
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
holder.account_dn.setText(Html.fromHtml(Helper.shortnameToUnicode(account.getDisplay_name(), true), Html.FROM_HTML_MODE_LEGACY));
|
||||
holder.account_un.setText(Html.fromHtml(Helper.shortnameToUnicode(account.getUsername(), true), Html.FROM_HTML_MODE_LEGACY));
|
||||
}else {
|
||||
//noinspection deprecation
|
||||
holder.account_dn.setText(Html.fromHtml(Helper.shortnameToUnicode(account.getDisplay_name(), true)));
|
||||
holder.account_un.setText(Html.fromHtml(Helper.shortnameToUnicode(account.getUsername(), true)));
|
||||
}
|
||||
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.mastodonC4);
|
||||
//Profile picture
|
||||
imageLoader.displayImage(account.getAvatar(), holder.account_pp, options);
|
||||
|
||||
if( account.isFollowing()){
|
||||
holder.account_follow.setVisibility(View.GONE);
|
||||
}else{
|
||||
holder.account_follow.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if( account.isRemote()) {
|
||||
holder.account_follow.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
holder.account_follow.setEnabled(false);
|
||||
new PostActionAsyncTask(context, API.StatusAction.REMOTE_FOLLOW, account.getAcct(), AccountSearchDevAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
}else {
|
||||
holder.account_follow.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
holder.account_follow.setEnabled(false);
|
||||
new PostActionAsyncTask(context, API.StatusAction.FOLLOW, account.getId(), AccountSearchDevAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
holder.acccount_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", account.getId());
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@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();
|
||||
holder.account_follow.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
for( Account account: accounts){
|
||||
if(account.getId().equals(userId)) {
|
||||
account.setFollowing(true);
|
||||
notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
holder.account_follow.setVisibility(View.GONE);
|
||||
Toast.makeText(context, R.string.toast_follow, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
|
||||
private class ViewHolder {
|
||||
LinearLayout acccount_container;
|
||||
ImageView account_pp;
|
||||
TextView account_dn;
|
||||
TextView account_un;
|
||||
FloatingActionButton account_follow;
|
||||
}
|
||||
|
||||
}
|
|
@ -143,9 +143,9 @@ public class AccountSearchWebAdapter extends BaseAdapter implements OnPostAction
|
|||
}
|
||||
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.mastodonC4);
|
||||
holder.account_ds.setAutoLinkMask(Linkify.WEB_URLS);
|
||||
holder.account_sc.setText(String.valueOf(account.getStatuses_count()));
|
||||
holder.account_fgc.setText(String.valueOf(account.getFollowing_count()));
|
||||
holder.account_frc.setText(String.valueOf(account.getFollowers_count()));
|
||||
holder.account_sc.setText(String.valueOf(account.getStatuses_count_str()));
|
||||
holder.account_fgc.setText(String.valueOf(account.getFollowing_count_str()));
|
||||
holder.account_frc.setText(String.valueOf(account.getFollowers_count_str()));
|
||||
//Profile picture
|
||||
imageLoader.displayImage(account.getAvatar(), holder.account_pp, options);
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
private NotificationsListAdapter notificationsListAdapter;
|
||||
private int behaviorWithAttachments;
|
||||
private boolean isOnWifi;
|
||||
private String targetedId;
|
||||
|
||||
|
||||
public NotificationsListAdapter(Context context, boolean isOnWifi, int behaviorWithAttachments, List<Notification> notifications){
|
||||
this.context = context;
|
||||
|
@ -170,6 +170,8 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
String type = notification.getType();
|
||||
String typeString = "";
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
Drawable imgH = null;
|
||||
switch (type){
|
||||
case "mention":
|
||||
holder.status_action_container.setVisibility(View.VISIBLE);
|
||||
|
@ -177,6 +179,12 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_mention));
|
||||
else
|
||||
typeString = String.format("@%s %s", notification.getAccount().getAcct(),context.getString(R.string.notif_mention));
|
||||
if( theme == Helper.THEME_DARK){
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_dark_1));
|
||||
}else {
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_light_1));
|
||||
}
|
||||
imgH = null;
|
||||
break;
|
||||
case "reblog":
|
||||
holder.status_action_container.setVisibility(View.GONE);
|
||||
|
@ -184,6 +192,12 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_reblog));
|
||||
else
|
||||
typeString = String.format("@%s %s", notification.getAccount().getAcct(),context.getString(R.string.notif_reblog));
|
||||
if( theme == Helper.THEME_DARK){
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_dark_2));
|
||||
}else {
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_light_2));
|
||||
}
|
||||
imgH = ContextCompat.getDrawable(context, R.drawable.ic_retweet_notif_header);
|
||||
break;
|
||||
case "favourite":
|
||||
holder.status_action_container.setVisibility(View.GONE);
|
||||
|
@ -191,6 +205,12 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_favourite));
|
||||
else
|
||||
typeString = String.format("@%s %s", notification.getAccount().getAcct(),context.getString(R.string.notif_favourite));
|
||||
if( theme == Helper.THEME_DARK){
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_dark_3));
|
||||
}else {
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_light_3));
|
||||
}
|
||||
imgH = ContextCompat.getDrawable(context, R.drawable.ic_fav_notif_header);
|
||||
break;
|
||||
case "follow":
|
||||
holder.status_action_container.setVisibility(View.GONE);
|
||||
|
@ -198,10 +218,24 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_follow));
|
||||
else
|
||||
typeString = String.format("@%s %s", notification.getAccount().getAcct(),context.getString(R.string.notif_follow));
|
||||
if( theme == Helper.THEME_DARK){
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_dark_4));
|
||||
}else {
|
||||
holder.card_status_container.setCardBackgroundColor(ContextCompat.getColor(context, R.color.notif_light_4));
|
||||
}
|
||||
imgH = ContextCompat.getDrawable(context, R.drawable.ic_follow_notif_header);
|
||||
break;
|
||||
}
|
||||
|
||||
changeDrawableColor(context, R.drawable.ic_retweet_notif_header,R.color.mastodonC4);
|
||||
changeDrawableColor(context, R.drawable.ic_fav_notif_header,R.color.mastodonC4);
|
||||
changeDrawableColor(context, R.drawable.ic_follow_notif_header,R.color.mastodonC4);
|
||||
holder.notification_type.setText(typeString);
|
||||
if( imgH != null) {
|
||||
holder.notification_type.setCompoundDrawablePadding((int)Helper.convertDpToPixel(5, context));
|
||||
imgH.setBounds(0, 0, (int) (20 * iconSizePercent / 100 * scale + 0.5f), (int) (20 * iconSizePercent / 100 * scale + 0.5f));
|
||||
}
|
||||
holder.notification_type.setCompoundDrawables( imgH, null, null, null);
|
||||
|
||||
holder.status_privacy.getLayoutParams().height = (int) Helper.convertDpToPixel((20*iconSizePercent/100), context);
|
||||
holder.status_privacy.getLayoutParams().width = (int) Helper.convertDpToPixel((20*iconSizePercent/100), context);
|
||||
holder.status_reply.getLayoutParams().height = (int) Helper.convertDpToPixel((20*iconSizePercent/100), context);
|
||||
|
@ -214,7 +248,6 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
|
||||
|
||||
//Manages theme for icon colors
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
if( theme == Helper.THEME_DARK){
|
||||
changeDrawableColor(context, R.drawable.ic_reply,R.color.dark_text);
|
||||
changeDrawableColor(context, R.drawable.ic_action_more,R.color.dark_text);
|
||||
|
@ -260,8 +293,13 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
}else{
|
||||
holder.notification_account_username.setCompoundDrawables( null, null, null, null);
|
||||
}
|
||||
String content = status.getContent();
|
||||
content = content.replaceAll("</p>","<br/><br/>");
|
||||
content = content.replaceAll("<p>","");
|
||||
if( content.endsWith("<br/><br/>") )
|
||||
content = content.substring(0,content.length() -10);
|
||||
|
||||
SpannableString spannableString = Helper.clickableElements(context, status.getContent(),
|
||||
SpannableString spannableString = Helper.clickableElements(context, content,
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(), true);
|
||||
holder.notification_status_content.setText(spannableString, TextView.BufferType.SPANNABLE);
|
||||
holder.notification_status_content.setMovementMethod(null);
|
||||
|
@ -402,7 +440,7 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
boolean confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true);
|
||||
boolean confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION_FAV, false);
|
||||
if( confirmation )
|
||||
displayConfirmationDialog(FAVOURITE,status);
|
||||
else
|
||||
|
@ -522,7 +560,7 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
*/
|
||||
private void displayConfirmationNotificationDialog(final Notification notification){
|
||||
final ArrayList seletedItems = new ArrayList();
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
AlertDialog dialog = new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.delete_notification_ask)
|
||||
.setMultiChoiceItems(new String[]{context.getString(R.string.delete_notification_ask_all)}, null, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
|
|
|
@ -14,6 +14,7 @@ package fr.gouv.etalab.mastodon.drawers;
|
|||
* 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.graphics.Paint;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
|
@ -90,6 +91,7 @@ import mastodon.etalab.gouv.fr.mastodon.R;
|
|||
|
||||
import static fr.gouv.etalab.mastodon.activities.MainActivity.currentLocale;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.shortnameToUnicode;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -197,7 +199,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
holder.status_prev4_container = (RelativeLayout) convertView.findViewById(R.id.status_prev4_container);
|
||||
holder.status_reply = (ImageView) convertView.findViewById(R.id.status_reply);
|
||||
holder.status_privacy = (ImageView) convertView.findViewById(R.id.status_privacy);
|
||||
holder.status_translate = (Button) convertView.findViewById(R.id.status_translate);
|
||||
holder.status_translate = (TextView) convertView.findViewById(R.id.status_translate);
|
||||
holder.status_content_translated_container = (LinearLayout) convertView.findViewById(R.id.status_content_translated_container);
|
||||
holder.main_container = (LinearLayout) convertView.findViewById(R.id.main_container);
|
||||
holder.status_spoiler_container = (LinearLayout) convertView.findViewById(R.id.status_spoiler_container);
|
||||
|
@ -205,9 +207,11 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
holder.status_spoiler = (TextView) convertView.findViewById(R.id.status_spoiler);
|
||||
holder.status_spoiler_button = (Button) convertView.findViewById(R.id.status_spoiler_button);
|
||||
holder.yandex_translate = (TextView) convertView.findViewById(R.id.yandex_translate);
|
||||
holder.google_translate = (TextView) convertView.findViewById(R.id.google_translate);
|
||||
holder.status_replies = (LinearLayout) convertView.findViewById(R.id.status_replies);
|
||||
holder.status_replies_profile_pictures = (LinearLayout) convertView.findViewById(R.id.status_replies_profile_pictures);
|
||||
holder.status_replies_text = (TextView) convertView.findViewById(R.id.status_replies_text);
|
||||
holder.new_element = (ImageView) convertView.findViewById(R.id.new_element);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
|
@ -217,7 +221,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
|
||||
//Display a preview for accounts that have replied *if enabled and only for home timeline*
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
boolean showPreview = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES, true);
|
||||
boolean showPreview = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES, false);
|
||||
if( showPreview){
|
||||
boolean showPreviewPP = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES_PP, true);
|
||||
if( status.getReplies() == null){
|
||||
|
@ -259,6 +263,11 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
}
|
||||
|
||||
}
|
||||
changeDrawableColor(context, R.drawable.ic_fiber_new,R.color.mastodonC4);
|
||||
if( status.isNew())
|
||||
holder.new_element.setVisibility(View.VISIBLE);
|
||||
else
|
||||
holder.new_element.setVisibility(View.GONE);
|
||||
int iconSizePercent = sharedpreferences.getInt(Helper.SET_ICON_SIZE, 130);
|
||||
int textSizePercent = sharedpreferences.getInt(Helper.SET_TEXT_SIZE, 110);
|
||||
|
||||
|
@ -301,6 +310,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
statusListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
holder.status_translate.setPaintFlags(holder.status_translate.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
||||
if( currentLocale != null && status.getLanguage() != null && !status.getLanguage().trim().equals(currentLocale) && !status.getLanguage().trim().equals("null")){
|
||||
if (translator != Helper.TRANS_NONE)
|
||||
holder.status_translate.setVisibility(View.VISIBLE);
|
||||
|
@ -310,10 +320,25 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
holder.status_translate.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if( translator == Helper.TRANS_YANDEX)
|
||||
holder.yandex_translate.setVisibility(View.VISIBLE);
|
||||
else
|
||||
holder.yandex_translate.setVisibility(View.GONE);
|
||||
switch (translator)
|
||||
{
|
||||
case Helper.TRANS_NONE:
|
||||
holder.yandex_translate.setVisibility(View.GONE);
|
||||
holder.google_translate.setVisibility(View.GONE);
|
||||
break;
|
||||
case Helper.TRANS_YANDEX:
|
||||
holder.google_translate.setVisibility(View.GONE);
|
||||
holder.yandex_translate.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case Helper.TRANS_GOOGLE:
|
||||
holder.yandex_translate.setVisibility(View.GONE);
|
||||
holder.google_translate.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
default:
|
||||
holder.yandex_translate.setVisibility(View.GONE);
|
||||
holder.google_translate.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
|
||||
holder.status_translate.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -340,6 +365,11 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
while (matcher.find()){
|
||||
String key = "__u" + String.valueOf(i) + "__";
|
||||
String value = matcher.group(0);
|
||||
int end = matcher.end();
|
||||
if (spannableString.charAt(end) == '/') {
|
||||
text = spannableString.toString().substring(0, end).
|
||||
concat(spannableString.toString().substring(end+1, spannableString.length()));
|
||||
}
|
||||
if( value != null) {
|
||||
urlConversion.put(key, value);
|
||||
text = text.replace(value, key);
|
||||
|
@ -361,9 +391,13 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
}
|
||||
if (translator == Helper.TRANS_YANDEX)
|
||||
new YandexQuery(StatusListAdapter.this).getYandexTextview(position, text, currentLocale);
|
||||
else if( translator == Helper.TRANS_GOOGLE)
|
||||
new GoogleTranslateQuery(StatusListAdapter.this).getGoogleTextview(position, text, currentLocale);
|
||||
else if( translator == Helper.TRANS_GOOGLE) {
|
||||
|
||||
while( text.charAt(text.length() -1) == '\n' && text.length() > 0)
|
||||
text = text.substring(0, text.length() -1);
|
||||
text += ".";
|
||||
new GoogleTranslateQuery(StatusListAdapter.this).getGoogleTextview(position, text.trim(), currentLocale);
|
||||
}
|
||||
}else {
|
||||
status.setTranslationShown(!status.isTranslationShown());
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
|
@ -381,6 +415,13 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
context.startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
holder.google_translate.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://translate.google.com/"));
|
||||
context.startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
//Toot was translated and user asked to see it
|
||||
if( status.isTranslationShown()){
|
||||
holder.status_content.setVisibility(View.GONE);
|
||||
|
@ -480,7 +521,10 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
}
|
||||
}
|
||||
|
||||
final String content, displayName, username, ppurl;
|
||||
String content;
|
||||
final String displayName;
|
||||
final String username;
|
||||
final String ppurl;
|
||||
if( status.getReblog() != null){
|
||||
content = status.getReblog().getContent();
|
||||
displayName = Helper.shortnameToUnicode(status.getReblog().getAccount().getDisplay_name(), true);
|
||||
|
@ -546,7 +590,10 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
});
|
||||
holder.status_content_translated.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
content = content.replaceAll("</p>","<br/><br/>");
|
||||
content = content.replaceAll("<p>","");
|
||||
if( content.endsWith("<br/><br/>") )
|
||||
content = content.substring(0,content.length() -10);
|
||||
final SpannableString spannableString = Helper.clickableElements(context,content,
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(), true);
|
||||
holder.status_content.setText(spannableString, TextView.BufferType.SPANNABLE);
|
||||
|
@ -712,7 +759,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
boolean confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true);
|
||||
boolean confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION_FAV, false);
|
||||
if( confirmation )
|
||||
displayConfirmationDialog(FAVOURITE,status);
|
||||
else
|
||||
|
@ -956,6 +1003,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
statuses.get(position).setContent_translated(aJsonString);
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
} catch (JSONException | UnsupportedEncodingException | IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, R.string.toast_error_translate, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
@ -965,6 +1013,16 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
JSONObject translationJson = new JSONObject(text);
|
||||
JSONArray aJsonArray = translationJson.getJSONArray("text");
|
||||
String aJsonString = aJsonArray.get(0).toString();
|
||||
|
||||
/* The one instance where I've seen this happen,
|
||||
the special tag was originally a hashtag ("__t1__"),
|
||||
that Yandex decided to change to a "__q1 - __".
|
||||
*/
|
||||
aJsonString = aJsonString.replaceAll("__q(\\d+) - __", "__t$1__");
|
||||
|
||||
// Noticed this in the very same toot
|
||||
aJsonString = aJsonString.replace("&", "&");
|
||||
|
||||
aJsonString = URLDecoder.decode(aJsonString, "UTF-8");
|
||||
return aJsonString;
|
||||
}
|
||||
|
@ -988,6 +1046,19 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
aJsonString = aJsonString.replace(" //","//");
|
||||
aJsonString = aJsonString.replace(" www .","www.");
|
||||
aJsonString = aJsonString.replace("www .","www.");
|
||||
|
||||
// This one might cause more trouble than it's worth
|
||||
aJsonString = aJsonString.replaceAll("\\* \\.", "*.");
|
||||
|
||||
/*
|
||||
Noticed that sometimes the special tags were getting messed up by Google,
|
||||
might be other variants, only caught one so far.
|
||||
|
||||
But, pre-planning might save some time later...
|
||||
*/
|
||||
aJsonString = aJsonString.replaceAll("__\\s?(u|t)\\s?(\\d+)\\s?__", "__$1$2__");
|
||||
aJsonString = aJsonString.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
|
||||
aJsonString = aJsonString.replaceAll("\\+", "%2B");
|
||||
aJsonString = URLDecoder.decode(aJsonString, "UTF-8");
|
||||
return aJsonString;
|
||||
}
|
||||
|
@ -1026,16 +1097,19 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
RelativeLayout status_prev4_container;
|
||||
ImageView status_reply;
|
||||
ImageView status_privacy;
|
||||
Button status_translate;
|
||||
TextView status_translate;
|
||||
LinearLayout status_container2;
|
||||
LinearLayout status_container3;
|
||||
LinearLayout main_container;
|
||||
TextView yandex_translate;
|
||||
TextView google_translate;
|
||||
|
||||
LinearLayout status_replies;
|
||||
LinearLayout status_replies_profile_pictures;
|
||||
TextView status_replies_text;
|
||||
LinearLayout loader_replies;
|
||||
|
||||
ImageView new_element;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,13 +31,14 @@ 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.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.drawers.NotificationsListAdapter;
|
||||
import fr.gouv.etalab.mastodon.drawers.StatusListAdapter;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
@ -66,12 +67,9 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private boolean swiped;
|
||||
private ListView lv_notifications;
|
||||
private DisplayNotificationsFragment displayNotificationsFragment;
|
||||
private TextView new_data;
|
||||
private String since_id;
|
||||
|
||||
public DisplayNotificationsFragment(){
|
||||
displayNotificationsFragment = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -138,27 +136,28 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
new_data.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
notificationsTmp = Helper.getTempNotification(context, null);
|
||||
if( notificationsTmp != null){
|
||||
for(int i = notificationsTmp.size() -1 ; i >= 0 ; i--){
|
||||
notifications.add(0,notificationsTmp.get(i));
|
||||
}
|
||||
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);
|
||||
}
|
||||
//The user clicked on the banner to refresh values so, the pointer is changed
|
||||
if( notificationsTmp.size() > 0 ) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, notificationsTmp.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
|
||||
lv_notifications.setAdapter(notificationsListAdapter);
|
||||
if( notificationsTmp.size() > 0){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notificationsTmp.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
if( notificationsTmp.size() > 0 && textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}
|
||||
new_data.setVisibility(View.GONE);
|
||||
notificationsTmp = new ArrayList<>();
|
||||
Helper.cacheNotificationsClear(context, null);
|
||||
((MainActivity) context).updateNotifCounter();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -188,11 +187,42 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
//New data are available
|
||||
notificationsTmp = Helper.getTempNotification(context, null);
|
||||
if (getUserVisibleHint() && notificationsTmp != null && notificationsTmp.size() > 0 && notifications.size() > 0) {
|
||||
ArrayList<String> added = new ArrayList<>();
|
||||
for(Notification notification : notifications){
|
||||
added.add(notification.getId());
|
||||
}
|
||||
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);
|
||||
for(int i = notificationsTmp.size() -1 ; i >= 0 ; i--){
|
||||
if( !added.contains(notificationsTmp.get(i).getId())) {
|
||||
this.notifications.add(0, notificationsTmp.get(i));
|
||||
added.add(notificationsTmp.get(i).getId());
|
||||
}
|
||||
}
|
||||
if( this.notifications.size() > 0 )
|
||||
max_id = this.notifications.get(this.notifications.size()-1).getId();
|
||||
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
|
||||
lv_notifications.setAdapter(notificationsListAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
if( isVisibleToUser )
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId, boolean refreshData) {
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
//UserId will be null here, so it needs to be retrieved from shared preferences
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
mainLoader.setVisibility(View.GONE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
if( apiResponse.getError() != null){
|
||||
|
@ -205,78 +235,34 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
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();
|
||||
since_id = apiResponse.getSince_id();
|
||||
String since_id = apiResponse.getSince_id();
|
||||
max_id = apiResponse.getMax_id();
|
||||
//The initial call comes from a classic tab refresh
|
||||
if( refreshData ) {
|
||||
manageNotifications(notifications, max_id, since_id);
|
||||
//The current tab is displayed, so user is supposed to have seen the notifications
|
||||
if( since_id != null && displayNotificationsFragment.getUserVisibleHint()) {
|
||||
editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, since_id);
|
||||
editor.apply();
|
||||
}else if(!displayNotificationsFragment.getUserVisibleHint()){
|
||||
//The refresh was done automatically, but the fragment was not displayed in viewpager
|
||||
//So the bubble counter will be displayed
|
||||
int countData = 0;
|
||||
//Retrieves new notification count
|
||||
if( bubble_max_id != null) {
|
||||
for (Notification nt : notifications) {
|
||||
if (nt.getId().trim().equals(bubble_max_id.trim()))
|
||||
break;
|
||||
countData++;
|
||||
}
|
||||
}
|
||||
((MainActivity)context).updateNotifCounter(countData);
|
||||
}
|
||||
}else { //Here, new values have been retrieved on the onResume call (forced mode)
|
||||
int countData = 0;
|
||||
if( bubble_max_id != null) {
|
||||
for (Notification nt : notifications) {
|
||||
if (nt.getId().trim().equals(bubble_max_id.trim()))
|
||||
break;
|
||||
countData++;
|
||||
}
|
||||
}
|
||||
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 notifications will be counted
|
||||
//The fragment is not displayed, so the bubble counter should be shown
|
||||
if (!displayNotificationsFragment.getUserVisibleHint()) {
|
||||
((MainActivity) context).updateNotifCounter(countData);
|
||||
} else { //The current fragment is visible, but for avoiding to populate with new values
|
||||
// a message will be displayed at the bottom requiring a click to display these new values
|
||||
new_data.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void manageNotifications(List<Notification> notifications, String max_id, String since_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
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
if( swiped ){
|
||||
Helper.cacheNotificationsClear(context,null);
|
||||
((MainActivity) context).updateNotifCounter();
|
||||
boolean isOnWifi = Helper.isOnWIFI(context);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, this.notifications);
|
||||
lv_notifications.setAdapter(notificationsListAdapter);
|
||||
swiped = false;
|
||||
}
|
||||
ArrayList<String> added = new ArrayList<>();
|
||||
for(Notification notification : this.notifications){
|
||||
added.add(notification.getId());
|
||||
}
|
||||
if( notifications != null && notifications.size() > 0) {
|
||||
for(Notification tmpNotification: notifications){
|
||||
this.notifications.add(tmpNotification);
|
||||
if( !added.contains(tmpNotification.getId())) {
|
||||
this.notifications.add(tmpNotification);
|
||||
added.add(tmpNotification.getId());
|
||||
}
|
||||
}
|
||||
notificationsListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
@ -284,52 +270,57 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
//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
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
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 && since_id != null){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + currentAccount.getId(), since_id);
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + currentAccount.getId(), notifications.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
firstLoad = false;
|
||||
}
|
||||
|
||||
|
||||
public void scrollToTop(){
|
||||
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 showNewContent(){
|
||||
new_data.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void refresh(){
|
||||
if( context == null)
|
||||
return;
|
||||
notificationsTmp = Helper.getTempNotification(context, null);
|
||||
if( notificationsTmp.size() > 0){
|
||||
ArrayList<String> added = new ArrayList<>();
|
||||
for(Notification notification : notifications){
|
||||
added.add(notification.getId());
|
||||
}
|
||||
for(int i = notificationsTmp.size() -1 ; i >= 0 ; i--){
|
||||
if( !added.contains(notificationsTmp.get(i).getId())) {
|
||||
this.notifications.add(0, notificationsTmp.get(i));
|
||||
added.add(notificationsTmp.get(i).getId());
|
||||
}
|
||||
}
|
||||
if( this.notifications.size() > 0 )
|
||||
max_id = this.notifications.get(this.notifications.size()-1).getId();
|
||||
boolean isOnWifi = Helper.isOnWIFI(context);
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notificationsTmp.get(0).getId());
|
||||
editor.apply();
|
||||
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
|
||||
lv_notifications.setAdapter(notificationsListAdapter);
|
||||
if( textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshData(){
|
||||
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
if(context != null && this.notificationsTmp != null && this.notificationsTmp.size() > 0){
|
||||
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);
|
||||
}
|
||||
if( textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
|
||||
lv_notifications.setAdapter(notificationsListAdapter);
|
||||
this.notificationsTmp = new ArrayList<>();
|
||||
}
|
||||
if( since_id != null){
|
||||
//The user clicked on the tab to refresh values so, the pointer is changed
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, since_id);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
new_data.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.support.v4.app.Fragment;
|
|||
import android.support.v4.content.LocalBroadcastManager;
|
||||
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;
|
||||
|
@ -75,20 +76,16 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
private boolean isOnWifi;
|
||||
private int behaviorWithAttachments;
|
||||
private boolean showMediaOnly;
|
||||
private DisplayStatusFragment displayStatusFragment;
|
||||
private TextView new_data;
|
||||
private int positionSpinnerTrans;
|
||||
private String since_id;
|
||||
private boolean hideHeader;
|
||||
private String instanceValue;
|
||||
|
||||
public DisplayStatusFragment(){
|
||||
displayStatusFragment = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
View rootView = inflater.inflate(R.layout.fragment_status, container, false);
|
||||
statuses = new ArrayList<>();
|
||||
context = getContext();
|
||||
|
@ -204,7 +201,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
R.color.mastodonC2,
|
||||
R.color.mastodonC3);
|
||||
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.USER)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.TAG)
|
||||
|
@ -222,27 +218,29 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
new_data.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
statusesTmp = Helper.getTempStatus(context, null);
|
||||
if( statusesTmp != null){
|
||||
for(int i = statusesTmp.size() -1 ; i >= 0 ; i--){
|
||||
statuses.add(0,statusesTmp.get(i));
|
||||
}
|
||||
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);
|
||||
}
|
||||
//The user clicked on the banner to refresh values so, the pointer is changed
|
||||
if( statusesTmp.size() > 0 ) {
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
if( statusesTmp.size() > 0){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, statusesTmp.get(0).getId());
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statusesTmp.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
if( statusesTmp.size() > 0 && textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
statusesTmp = new ArrayList<>();
|
||||
}
|
||||
new_data.setVisibility(View.GONE);
|
||||
statusesTmp = new ArrayList<>();
|
||||
Helper.cacheStatusClear(context, null);
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -261,24 +259,29 @@ 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);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
statuses = new ArrayList<>();
|
||||
for(Status status: statusesTmp){
|
||||
statuses.add(status);
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
//New data are available
|
||||
statusesTmp = Helper.getTempStatus(context, null);
|
||||
if (getUserVisibleHint() && statusesTmp != null && statusesTmp.size() > 0 && statuses.size() > 0) {
|
||||
ArrayList<String> added = new ArrayList<>();
|
||||
for (Status status : statuses) {
|
||||
added.add(status.getId());
|
||||
}
|
||||
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);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
for (int i = statusesTmp.size() - 1; i >= 0; i--) {
|
||||
if (!added.contains(statusesTmp.get(i).getId())) {
|
||||
this.statuses.add(0, statusesTmp.get(i));
|
||||
added.add(statusesTmp.get(i).getId());
|
||||
}
|
||||
}
|
||||
if (this.statuses.size() > 0)
|
||||
max_id = this.statuses.get(this.statuses.size() - 1).getId();
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
}
|
||||
//The user clicked on the tab to refresh values so, the pointer is changed
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, statusesTmp.get(0).getId());
|
||||
editor.apply();
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
statusesTmp = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,87 +316,33 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
return;
|
||||
}
|
||||
List<Status> statuses = apiResponse.getStatuses();
|
||||
since_id = apiResponse.getSince_id();
|
||||
String since_id = apiResponse.getSince_id();
|
||||
max_id = apiResponse.getMax_id();
|
||||
//Special case for home timeline
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME){
|
||||
//Retrieves some values
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
String bubble_max_id = sharedpreferences.getString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, null);
|
||||
//The initial call comes from a classic tab refresh
|
||||
|
||||
if( refreshData ) {
|
||||
|
||||
manageStatus(statuses, max_id, since_id);
|
||||
//The current tab is displayed, so user is supposed to have seen status
|
||||
if( since_id != null && displayStatusFragment.getUserVisibleHint()) {
|
||||
editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, since_id);
|
||||
editor.apply();
|
||||
}else if(!displayStatusFragment.getUserVisibleHint()){
|
||||
//Current fragment was loaded but not displayed to the user.
|
||||
//So the bubble counter will be displayed
|
||||
int countData = 0;
|
||||
//Retrieves new status count
|
||||
if( bubble_max_id != null) {
|
||||
for (Status st : statuses) {
|
||||
if (st.getId().trim().equals(bubble_max_id.trim()))
|
||||
break;
|
||||
countData++;
|
||||
}
|
||||
}
|
||||
((MainActivity)context).updateHomeCounter(countData);
|
||||
}
|
||||
}else { //Here, new values have been retrieved on the onResume call (forced mode)
|
||||
int countData = 0;
|
||||
if( bubble_max_id != null) {
|
||||
for (Status st : statuses) {
|
||||
if (st.getId().trim().equals(bubble_max_id.trim()))
|
||||
break;
|
||||
countData++;
|
||||
}
|
||||
}
|
||||
|
||||
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 status will be counted
|
||||
//The fragment is not displayed, so the bubble counter should be shown
|
||||
if (!displayStatusFragment.getUserVisibleHint()) {
|
||||
((MainActivity) context).updateHomeCounter(countData);
|
||||
} else {
|
||||
//The current fragment is visible, but for avoiding to populate with new values
|
||||
//Values are put in temp and the banned is displayed
|
||||
new_data.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
manageStatus(statuses, max_id, since_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void manageStatus(List<Status> statuses, String max_id, String since_id){
|
||||
flag_loading = (max_id == null );
|
||||
if( !swiped && firstLoad && (statuses == null || statuses.size() == 0))
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
else
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
if( swiped ){
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
Helper.cacheStatusClear(context,null);
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
}
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, this.statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
swiped = false;
|
||||
}
|
||||
ArrayList<String> added = new ArrayList<>();
|
||||
for(Status status : this.statuses){
|
||||
added.add(status.getId());
|
||||
}
|
||||
if( statuses != null && statuses.size() > 0) {
|
||||
for(Status tmpStatus: statuses){
|
||||
this.statuses.add(tmpStatus);
|
||||
if( !added.contains(tmpStatus.getId())) {
|
||||
this.statuses.add(tmpStatus);
|
||||
added.add(tmpStatus.getId());
|
||||
}
|
||||
}
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
@ -401,14 +350,13 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
|
||||
//Store last toot id for home timeline to avoid to notify for those that have been already seen
|
||||
if(statuses != null && statuses.size() > 0 && type == RetrieveFeedsAsyncTask.Type.HOME ){
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
//acct is null when used in Fragment, data need to be retrieved via shared preferences and db
|
||||
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 && since_id != null){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + currentAccount.getId(), since_id);
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + currentAccount.getId(), statuses.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
@ -416,8 +364,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
|
||||
//Retrieves replies
|
||||
if(statuses != null && statuses.size() > 0 && type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean showPreview = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES, true);
|
||||
boolean showPreview = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES, false);
|
||||
//Retrieves attached replies to a toot
|
||||
if (showPreview) {
|
||||
new RetrieveRepliesAsyncTask(context, statuses, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
@ -425,6 +372,52 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
}
|
||||
}
|
||||
|
||||
public void showNewContent(){
|
||||
new_data.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
if( isVisibleToUser )
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void refresh(){
|
||||
//New data are available
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
if (context == null)
|
||||
return;
|
||||
statusesTmp = Helper.getTempStatus(context, null);
|
||||
if (statusesTmp.size() > 0) {
|
||||
ArrayList<String> added = new ArrayList<>();
|
||||
for (Status status : statuses) {
|
||||
added.add(status.getId());
|
||||
}
|
||||
for (int i = statusesTmp.size() - 1; i >= 0; i--) {
|
||||
if (!added.contains(statusesTmp.get(i).getId())) {
|
||||
this.statuses.add(0, statusesTmp.get(i));
|
||||
added.add(statusesTmp.get(i).getId());
|
||||
}
|
||||
}
|
||||
if (this.statuses.size() > 0)
|
||||
max_id = this.statuses.get(this.statuses.size() - 1).getId();
|
||||
boolean isOnWifi = Helper.isOnWIFI(context);
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statusesTmp.get(0).getId());
|
||||
editor.apply();
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
if (textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}
|
||||
new_data.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollToTop(){
|
||||
if( lv_status != null)
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
|
@ -444,36 +437,4 @@ 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(){
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if(context != null && this.statusesTmp != null && this.statusesTmp.size() > 0){
|
||||
|
||||
boolean isOnWifi = Helper.isOnWIFI(context);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
|
||||
statuses = new ArrayList<>();
|
||||
for(Status status: statusesTmp){
|
||||
statuses.add(status);
|
||||
}
|
||||
if( textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
statusesTmp = new ArrayList<>();
|
||||
}
|
||||
if( since_id != null){
|
||||
//The user clicked on the tab to refresh values so, the pointer is changed
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, since_id);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,19 +94,6 @@ 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);
|
||||
|
@ -133,7 +120,7 @@ public class SettingsFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
boolean preview_reply = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES, true);
|
||||
boolean preview_reply = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES, false);
|
||||
final CheckBox set_preview_reply = (CheckBox) rootView.findViewById(R.id.set_preview_reply);
|
||||
final LinearLayout set_preview_reply_pp_container = (LinearLayout) rootView.findViewById(R.id.set_preview_reply_pp_container);
|
||||
final SwitchCompat set_preview_reply_pp = (SwitchCompat) rootView.findViewById(R.id.set_preview_reply_pp);
|
||||
|
@ -152,6 +139,7 @@ public class SettingsFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
if( !preview_reply){
|
||||
set_preview_reply_pp_container.setVisibility(View.GONE);
|
||||
}else{
|
||||
|
@ -181,6 +169,53 @@ public class SettingsFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
boolean notif_validation_fav = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION_FAV, false);
|
||||
final CheckBox set_share_validation_fav = (CheckBox) rootView.findViewById(R.id.set_share_validation_fav);
|
||||
set_share_validation_fav.setChecked(notif_validation_fav);
|
||||
|
||||
set_share_validation_fav.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SET_NOTIF_VALIDATION_FAV, set_share_validation_fav.isChecked());
|
||||
editor.apply();
|
||||
}
|
||||
});
|
||||
|
||||
boolean display_local = sharedpreferences.getBoolean(Helper.SET_DISPLAY_LOCAL, true);
|
||||
final CheckBox set_display_local = (CheckBox) rootView.findViewById(R.id.set_display_local);
|
||||
set_display_local.setChecked(display_local);
|
||||
|
||||
set_display_local.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SET_DISPLAY_LOCAL, set_display_local.isChecked());
|
||||
editor.apply();
|
||||
getActivity().recreate();
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(INTENT_ACTION, CHANGE_THEME_INTENT);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
boolean display_global = sharedpreferences.getBoolean(Helper.SET_DISPLAY_GLOBAL, true);
|
||||
final CheckBox set_display_global = (CheckBox) rootView.findViewById(R.id.set_display_global);
|
||||
set_display_global.setChecked(display_global);
|
||||
|
||||
set_display_global.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SET_DISPLAY_GLOBAL, set_display_global.isChecked());
|
||||
editor.apply();
|
||||
getActivity().recreate();
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(INTENT_ACTION, CHANGE_THEME_INTENT);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
final CheckBox set_embedded_browser = (CheckBox) rootView.findViewById(R.id.set_embedded_browser);
|
||||
final LinearLayout set_javascript_container = (LinearLayout) rootView.findViewById(R.id.set_javascript_container);
|
||||
|
|
|
@ -26,10 +26,14 @@ import android.support.v7.widget.SwitchCompat;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
@ -49,6 +53,9 @@ public class SettingsNotificationsFragment extends Fragment {
|
|||
|
||||
private Context context;
|
||||
private int style;
|
||||
|
||||
int count = 0;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
|
@ -217,6 +224,10 @@ public class SettingsNotificationsFragment extends Fragment {
|
|||
|
||||
}
|
||||
});
|
||||
|
||||
final Spinner led_colour_spinner = (Spinner) rootView.findViewById(R.id.led_colour_spinner);
|
||||
final TextView ledLabel = (TextView) rootView.findViewById(R.id.set_led_colour_label);
|
||||
|
||||
switchCompatSilent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
|
@ -224,8 +235,55 @@ public class SettingsNotificationsFragment extends Fragment {
|
|||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SET_NOTIF_SILENT, isChecked);
|
||||
editor.apply();
|
||||
|
||||
if (isChecked) {
|
||||
ledLabel.setEnabled(true);
|
||||
led_colour_spinner.setEnabled(true);
|
||||
} else {
|
||||
ledLabel.setEnabled(false);
|
||||
for (View lol : led_colour_spinner.getTouchables()) {
|
||||
lol.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (sharedpreferences.getBoolean(Helper.SET_NOTIF_SILENT, false)) {
|
||||
|
||||
ledLabel.setEnabled(true);
|
||||
led_colour_spinner.setEnabled(true);
|
||||
|
||||
ArrayAdapter<CharSequence> adapterLEDColour = ArrayAdapter.createFromResource(getActivity(),
|
||||
R.array.led_colours, android.R.layout.simple_spinner_item);
|
||||
led_colour_spinner.setAdapter(adapterLEDColour);
|
||||
int positionSpinnerLEDColour = (sharedpreferences.getInt(Helper.SET_LED_COLOUR, Helper.LED_COLOUR));
|
||||
led_colour_spinner.setSelection(positionSpinnerLEDColour);
|
||||
|
||||
led_colour_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (count > 0) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putInt(Helper.SET_LED_COLOUR, position);
|
||||
editor.apply();
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
else {
|
||||
ledLabel.setEnabled(false);
|
||||
for (View lol : led_colour_spinner.getTouchables()) {
|
||||
lol.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if( theme == Helper.THEME_LIGHT) {
|
||||
settings_time_from.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
settings_time_to.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
|
|
|
@ -43,7 +43,6 @@ public class TabLayoutSettingsFragment extends Fragment {
|
|||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.settings)));
|
||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.notifications)));
|
||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.optimization)));
|
||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.profile)));
|
||||
final ViewPager viewPager = (ViewPager) inflatedView.findViewById(R.id.viewpager);
|
||||
|
||||
viewPager.setAdapter(new PagerAdapter
|
||||
|
@ -90,8 +89,6 @@ public class TabLayoutSettingsFragment extends Fragment {
|
|||
return new SettingsNotificationsFragment();
|
||||
case 2:
|
||||
return new SettingsOptimizationFragment();
|
||||
case 3:
|
||||
return new SettingsProfileFragment();
|
||||
default:
|
||||
return new SettingsNotificationsFragment();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package fr.gouv.etalab.mastodon.helper;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 03/09/2017.
|
||||
* Expanded listview
|
||||
*/
|
||||
|
||||
public class ExpandableHeightListView extends ListView
|
||||
{
|
||||
|
||||
boolean expanded = false;
|
||||
|
||||
public ExpandableHeightListView(Context context)
|
||||
{
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ExpandableHeightListView(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ExpandableHeightListView(Context context, AttributeSet attrs,int defStyle)
|
||||
{
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public boolean isExpanded()
|
||||
{
|
||||
return expanded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
|
||||
{
|
||||
// HACK! TAKE THAT ANDROID!
|
||||
if (isExpanded())
|
||||
{
|
||||
// Calculate entire height by providing a very large height hint.
|
||||
// But do not use the highest 2 bits of this integer; those are
|
||||
// reserved for the MeasureSpec mode.
|
||||
int expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
|
||||
super.onMeasure(widthMeasureSpec, expandSpec);
|
||||
|
||||
ViewGroup.LayoutParams params = getLayoutParams();
|
||||
params.height = getMeasuredHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
public void setExpanded(boolean expanded)
|
||||
{
|
||||
this.expanded = expanded;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@ package fr.gouv.etalab.mastodon.helper;
|
|||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.app.DownloadManager;
|
||||
|
@ -81,6 +83,7 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.loopj.android.http.BuildConfig;
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
|
@ -92,19 +95,23 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
|||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.InetAddress;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -116,6 +123,7 @@ import java.util.TimeZone;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.EditProfileActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.HashTagActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.LoginActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
|
@ -126,14 +134,13 @@ import fr.gouv.etalab.mastodon.asynctasks.RemoveAccountAsyncTask;
|
|||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
import static android.app.Notification.DEFAULT_VIBRATE;
|
||||
import static android.app.Notification.FLAG_SHOW_LIGHTS;
|
||||
import static android.content.Context.DOWNLOAD_SERVICE;
|
||||
|
||||
|
||||
|
@ -177,10 +184,6 @@ 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;
|
||||
|
@ -204,8 +207,10 @@ 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 String SET_TRANSLATOR = "set_translator";
|
||||
public static final String SET_LED_COLOUR = "set_led_colour";
|
||||
private static final String SET_TEMP_STATUS = "set_temp_status";
|
||||
private static final String SET_TEMP_NOTIFICATIONS = "set_temp_notifications";
|
||||
|
||||
public static final int ATTACHMENT_ALWAYS = 1;
|
||||
public static final int ATTACHMENT_WIFI = 2;
|
||||
|
@ -216,6 +221,8 @@ public class Helper {
|
|||
public static final int THEME_MENU = 2;
|
||||
public static final int THEME_MENU_TABS = 3;
|
||||
|
||||
public static final int LED_COLOUR = 0;
|
||||
|
||||
public static final int TRANS_YANDEX = 0;
|
||||
public static final int TRANS_GOOGLE = 1;
|
||||
public static final int TRANS_NONE = 2;
|
||||
|
@ -226,6 +233,7 @@ public class Helper {
|
|||
public static final String SET_NOTIF_MENTION = "set_notif_follow_mention";
|
||||
public static final String SET_NOTIF_SHARE = "set_notif_follow_share";
|
||||
public static final String SET_NOTIF_VALIDATION = "set_share_validation";
|
||||
public static final String SET_NOTIF_VALIDATION_FAV = "set_share_validation_fav";
|
||||
public static final String SET_WIFI_ONLY = "set_wifi_only";
|
||||
public static final String SET_NOTIF_HOMETIMELINE = "set_notif_hometimeline";
|
||||
public static final String SET_NOTIF_SILENT = "set_notif_silent";
|
||||
|
@ -235,6 +243,8 @@ public class Helper {
|
|||
public static final String SET_COOKIES = "set_cookies";
|
||||
public static final String SET_FOLDER_RECORD = "set_folder_record";
|
||||
public static final String SET_TOOT_VISIBILITY = "set_toot_visibility";
|
||||
public static final String SET_DISPLAY_LOCAL = "set_display_local";
|
||||
public static final String SET_DISPLAY_GLOBAL = "set_display_global";
|
||||
|
||||
//End points
|
||||
public static final String EP_AUTHORIZE = "/oauth/authorize";
|
||||
|
@ -250,7 +260,8 @@ public class Helper {
|
|||
//Receiver
|
||||
public static final String SEARCH_VALIDATE_ACCOUNT = "search_validate_account";
|
||||
public static final String HEADER_ACCOUNT = "header_account";
|
||||
|
||||
public static final String RECEIVE_DATA = "receive_data";
|
||||
public static final String RECEIVE_PICTURE = "receive_picture";
|
||||
//User agent
|
||||
public static final String USER_AGENT = "Mastalab/"+ BuildConfig.VERSION_NAME + " Android/"+ Build.VERSION.RELEASE;
|
||||
|
||||
|
@ -258,7 +269,7 @@ public class Helper {
|
|||
private static boolean menuAccountsOpened = false;
|
||||
|
||||
|
||||
private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":([-+\\w]+):");
|
||||
private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":( |)([-+\\w]+):");
|
||||
|
||||
public static final Pattern urlPattern = Pattern.compile(
|
||||
"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,10}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))",
|
||||
|
@ -273,18 +284,26 @@ public class Helper {
|
|||
*/
|
||||
public static String shortnameToUnicode(String input, boolean removeIfUnsupported) {
|
||||
Matcher matcher = SHORTNAME_PATTERN.matcher(input);
|
||||
|
||||
boolean supported = Build.VERSION.SDK_INT >= 16;
|
||||
while (matcher.find()) {
|
||||
String unicode = emoji.get(matcher.group(1));
|
||||
String unicode = emoji.get(matcher.group(2));
|
||||
if (unicode == null) {
|
||||
continue;
|
||||
}
|
||||
if (supported) {
|
||||
input = input.replace(":" + matcher.group(1) + ":", unicode);
|
||||
if (matcher.group(1).equals(" "))
|
||||
input = input.replace(": " + matcher.group(2) + ":", unicode);
|
||||
else
|
||||
input = input.replace(":" + matcher.group(2) + ":", unicode);
|
||||
} else if (removeIfUnsupported) {
|
||||
input = input.replace(":" + matcher.group(1) + ":", "");
|
||||
if (matcher.group(1).equals(" "))
|
||||
input = input.replace(": " + matcher.group(2) + ":", unicode);
|
||||
else
|
||||
input = input.replace(":" + matcher.group(2) + ":", "");
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
//Emoji manager
|
||||
|
@ -596,16 +615,40 @@ public class Helper {
|
|||
.setAutoCancel(true)
|
||||
.setContentIntent(pIntent)
|
||||
.setContentText(message);
|
||||
|
||||
int notifDefaults = FLAG_SHOW_LIGHTS;
|
||||
notificationBuilder.setDefaults(notifDefaults);
|
||||
if( sharedpreferences.getBoolean(Helper.SET_NOTIF_SILENT,false) ) {
|
||||
notificationBuilder.setDefaults(notifDefaults|DEFAULT_VIBRATE);
|
||||
notificationBuilder.setVibrate(new long[] { 500, 500, 500});
|
||||
}else {
|
||||
String soundUri = ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() +"/";
|
||||
notificationBuilder.setSound(Uri.parse(soundUri + R.raw.boop));
|
||||
}
|
||||
notificationBuilder.setLights(Color.BLUE, 500, 1000);
|
||||
|
||||
int ledColour = Color.BLUE;
|
||||
|
||||
switch (sharedpreferences.getInt(Helper.SET_LED_COLOUR, Helper.LED_COLOUR)) {
|
||||
case 0: // BLUE
|
||||
ledColour = Color.BLUE;
|
||||
break;
|
||||
case 1: // CYAN
|
||||
ledColour = Color.CYAN;
|
||||
break;
|
||||
case 2: // MAGENTA
|
||||
ledColour = Color.MAGENTA;
|
||||
break;
|
||||
case 3: // GREEN
|
||||
ledColour = Color.GREEN;
|
||||
break;
|
||||
case 4: // RED
|
||||
ledColour = Color.RED;
|
||||
break;
|
||||
case 5: // YELLOW
|
||||
ledColour = Color.YELLOW;
|
||||
break;
|
||||
case 6: // WHITE
|
||||
ledColour = Color.WHITE;
|
||||
break;
|
||||
}
|
||||
|
||||
notificationBuilder.setLights(ledColour, 500, 1000);
|
||||
notificationBuilder.setContentTitle(title);
|
||||
notificationBuilder.setLargeIcon(icon);
|
||||
notificationManager.notify(notificationId, notificationBuilder.build());
|
||||
|
@ -964,6 +1007,8 @@ public class Helper {
|
|||
TextView ownerStatus = (TextView) headerLayout.findViewById(R.id.owner_status);
|
||||
TextView ownerFollowing = (TextView) headerLayout.findViewById(R.id.owner_following);
|
||||
TextView ownerFollowers = (TextView) headerLayout.findViewById(R.id.owner_followers);
|
||||
ImageView header_edit_profile = (ImageView) headerLayout.findViewById(R.id.header_edit_profile);
|
||||
header_edit_profile.setOnClickListener(null);
|
||||
if( account == null ) {
|
||||
Helper.logout(activity);
|
||||
Intent myIntent = new Intent(activity, LoginActivity.class);
|
||||
|
@ -1013,6 +1058,13 @@ public class Helper {
|
|||
}
|
||||
});
|
||||
}
|
||||
header_edit_profile.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(activity, EditProfileActivity.class);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
profilePicture.setOnClickListener(null);
|
||||
profilePicture.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -1544,4 +1596,124 @@ public class Helper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int getUnreadNotifications(Context context, String userId){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Gson gson = new Gson();
|
||||
String json = sharedpreferences.getString(Helper.SET_TEMP_NOTIFICATIONS + userId, null);
|
||||
Type type = new TypeToken<ArrayList<Notification>>() {}.getType();
|
||||
ArrayList<Notification> notifications = gson.fromJson(json, type);
|
||||
return (notifications == null)?0:notifications.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int getUnreadToots(Context context, String userId){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Gson gson = new Gson();
|
||||
String json = sharedpreferences.getString(Helper.SET_TEMP_STATUS + userId, null);
|
||||
Type type = new TypeToken<ArrayList<Status>>() {}.getType();
|
||||
ArrayList<Status> statuses = gson.fromJson(json, type);
|
||||
return (statuses == null)?0:statuses.size();
|
||||
}
|
||||
|
||||
|
||||
public static void cacheStatus(Context context, Status status, String userId){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
ArrayList<Status> statuses = getTempStatus(context, userId);
|
||||
if( statuses == null)
|
||||
statuses = new ArrayList<>();
|
||||
if( status != null)
|
||||
statuses.add(0,status);
|
||||
Gson gson = new Gson();
|
||||
String serializedAccounts = gson.toJson(statuses);
|
||||
editor.putString(Helper.SET_TEMP_STATUS + userId, serializedAccounts);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public static void cacheStatusClear(Context context, String userId){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
ArrayList<Status> statuses = new ArrayList<>();
|
||||
Gson gson = new Gson();
|
||||
String serializedAccounts = gson.toJson(statuses);
|
||||
editor.putString(Helper.SET_TEMP_STATUS + userId, serializedAccounts);
|
||||
editor.apply();
|
||||
//noinspection EmptyTryBlock
|
||||
try {
|
||||
NotificationManager notificationManager = (NotificationManager) context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
long notif_id = Long.parseLong(userId);
|
||||
int notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2);
|
||||
notificationManager.cancel(notificationId);
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
|
||||
public static ArrayList<Status> getTempStatus(Context context, String userId){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Gson gson = new Gson();
|
||||
String json = sharedpreferences.getString(Helper.SET_TEMP_STATUS + userId, null);
|
||||
Type type = new TypeToken<ArrayList<Status>>() {}.getType();
|
||||
return gson.fromJson(json, type);
|
||||
}
|
||||
|
||||
|
||||
public static void cacheNotifications(Context context, Notification notification, String userId){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
ArrayList<Notification> notifications = getTempNotification(context, userId);
|
||||
if( notifications == null)
|
||||
notifications = new ArrayList<>();
|
||||
if( notification != null)
|
||||
notifications.add(0,notification);
|
||||
Gson gson = new Gson();
|
||||
String serializedAccounts = gson.toJson(notifications);
|
||||
editor.putString(Helper.SET_TEMP_NOTIFICATIONS + userId, serializedAccounts);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public static void cacheNotificationsClear(Context context, String userId){
|
||||
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
ArrayList<Notification> notifications = new ArrayList<>();
|
||||
Gson gson = new Gson();
|
||||
String serializedAccounts = gson.toJson(notifications);
|
||||
editor.putString(Helper.SET_TEMP_NOTIFICATIONS + userId, serializedAccounts);
|
||||
editor.apply();
|
||||
//noinspection EmptyTryBlock
|
||||
try {
|
||||
NotificationManager notificationManager = (NotificationManager) context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
long notif_id = Long.parseLong(userId);
|
||||
int notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
|
||||
notificationManager.cancel(notificationId);
|
||||
}catch (Exception ignored){}
|
||||
|
||||
}
|
||||
|
||||
public static ArrayList<Notification> getTempNotification(Context context, String userId){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( userId == null)
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Gson gson = new Gson();
|
||||
String json = sharedpreferences.getString(Helper.SET_TEMP_NOTIFICATIONS + userId, null);
|
||||
Type type = new TypeToken<ArrayList<Notification>>() {}.getType();
|
||||
return gson.fromJson(json, type);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package fr.gouv.etalab.mastodon.helper;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 02/09/2017.
|
||||
*/
|
||||
|
||||
public class ManageHeader {
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/* 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>. */
|
||||
package fr.gouv.etalab.mastodon.interfaces;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 02/09/2017.
|
||||
* Interface for retrieving meta data
|
||||
*/
|
||||
public interface OnRetrieveMetaDataInterface {
|
||||
void onRetrieveMetaData(boolean error, String image, String title, String description);
|
||||
}
|
|
@ -20,5 +20,5 @@ package fr.gouv.etalab.mastodon.interfaces;
|
|||
* Interface for retrieving a remote account
|
||||
*/
|
||||
public interface OnRetrieveRemoteAccountInterface {
|
||||
void onRetrieveRemoteAccount(boolean error, String name, String username, boolean locked, String avatar, String bio, int statusCount, int followingCount, int followersCount);
|
||||
void onRetrieveRemoteAccount(boolean error, String name, String username, String instance, boolean locked, String avatar, String bio, String statusCount, String followingCount, String followersCount);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* 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>. */
|
||||
package fr.gouv.etalab.mastodon.interfaces;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 03/09/2017.
|
||||
* Interface for search dev accounts
|
||||
*/
|
||||
public interface OnRetrieveSearchDevelopersAccountshInterface {
|
||||
void onRetrieveSearchDevelopersAccounts(ArrayList<Account> accounts);
|
||||
}
|
|
@ -127,24 +127,17 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe
|
|||
|
||||
|
||||
@Override
|
||||
public void onRetrieveHomeTimelineService(APIResponse apiResponse, String acct, String userId) {
|
||||
List<Status> statuses = apiResponse.getStatuses();
|
||||
public void onRetrieveHomeTimelineService(APIResponse apiResponse, String acct, final String userId) {
|
||||
final List<Status> statuses = apiResponse.getStatuses();
|
||||
if( apiResponse.getError() != null || statuses == null || statuses.size() == 0)
|
||||
return;
|
||||
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
final String max_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, null);
|
||||
if( max_id == null){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, apiResponse.getSince_id());
|
||||
editor.apply();
|
||||
return;
|
||||
}
|
||||
|
||||
//No previous notifications in cache, so no notification will be sent
|
||||
String message;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, apiResponse.getSince_id());
|
||||
editor.apply();
|
||||
|
||||
for(Status status: statuses){
|
||||
//The notification associated to max_id is discarded as it is supposed to have already been sent
|
||||
//Also, if the toot comes from the owner, we will avoid to warn him/her...
|
||||
|
@ -189,11 +182,17 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe
|
|||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||
super.onLoadingComplete(imageUri, view, loadedImage);
|
||||
notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, finalMessage);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
@Override
|
||||
public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){
|
||||
notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
|
||||
R.drawable.mastodonlogo), finalTitle, finalMessage);
|
||||
R.drawable.mastodonlogo), finalTitle, finalMessage);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
|
||||
editor.apply();
|
||||
}});
|
||||
|
||||
}
|
||||
|
@ -201,4 +200,4 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -133,8 +133,8 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
|
|||
|
||||
|
||||
@Override
|
||||
public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId, boolean refreshData) {
|
||||
List<Notification> notifications = apiResponse.getNotifications();
|
||||
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)
|
||||
return;
|
||||
Bitmap icon_notification = null;
|
||||
|
@ -144,12 +144,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
|
|||
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);
|
||||
if( max_id == null){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, apiResponse.getSince_id());
|
||||
editor.apply();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//No previous notifications in cache, so no notification will be sent
|
||||
int newFollows = 0;
|
||||
|
@ -176,7 +171,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
|
|||
title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_mention));
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "reblog":
|
||||
if(notif_share){
|
||||
newShare++;
|
||||
|
@ -217,9 +212,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
|
|||
default:
|
||||
}
|
||||
}
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, apiResponse.getSince_id());
|
||||
editor.apply();
|
||||
|
||||
int allNotifCount = newFollows + newAdds + newAsks + newMentions + newShare;
|
||||
if( allNotifCount > 0){
|
||||
//Some others notification
|
||||
|
@ -254,18 +247,26 @@ 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)
|
||||
if( max_id != null) {
|
||||
notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, message);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notifications.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){
|
||||
if( max_id != null)
|
||||
if( max_id != null) {
|
||||
notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
|
||||
R.drawable.mastodonlogo), finalTitle, message);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notifications.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ package fr.gouv.etalab.mastodon.jobs;
|
|||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import com.evernote.android.job.Job;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package fr.gouv.etalab.mastodon.services;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 29/08/2017.
|
||||
* BroadcastReceiver to start service when device boot
|
||||
*/
|
||||
|
||||
public class BootService extends BroadcastReceiver {
|
||||
|
||||
public BootService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
List<Account> accounts = new AccountDAO(context, db).getAllAccount();
|
||||
if( accounts != null){
|
||||
for (Account account: accounts) {
|
||||
Intent intentService = new Intent(context, StreamingService.class);
|
||||
intentService.putExtra("acccountId", account.getId());
|
||||
intentService.putExtra("accountAcct", account.getAcct());
|
||||
context.startService(intentService);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,503 @@
|
|||
package fr.gouv.etalab.mastodon.services;
|
||||
/* 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>. */
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.StrictMode;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||
import fr.gouv.etalab.mastodon.client.TLSSocketFactory;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
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.canNotify;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.notify_user;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 28/08/2017.
|
||||
* Manage service for streaming api and new notifications
|
||||
*/
|
||||
|
||||
public class StreamingService extends Service {
|
||||
|
||||
private String message;
|
||||
private int notificationId;
|
||||
private Intent intent;
|
||||
private String lastPreviousContent;
|
||||
private static HashMap<String, HttpsURLConnection> connectionHashMap = new HashMap<>();
|
||||
private static HashMap<String, Boolean> isConnectingHashMap = new HashMap<>();
|
||||
private EventStreaming lastEvent;
|
||||
public enum EventStreaming{
|
||||
UPDATE,
|
||||
NOTIFICATION,
|
||||
DELETE,
|
||||
NONE
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if( intent != null){
|
||||
String accountId = intent.getStringExtra("accountId");
|
||||
String accountAcct = intent.getStringExtra("accountAcct");
|
||||
if( accountId != null && accountAcct != null){
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account account = new AccountDAO(getApplicationContext(), db).getAccountByIDAcct(accountId, accountAcct);
|
||||
if( account != null)
|
||||
callAsynchronousTask(account);
|
||||
}else {
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
List<Account> accounts = new AccountDAO(getApplicationContext(), db).getAllAccount();
|
||||
if( accounts != null){
|
||||
for (Account account: accounts) {
|
||||
intent = new Intent(getApplicationContext(), StreamingService.class);
|
||||
intent.putExtra("accountId", account.getId());
|
||||
intent.putExtra("accountAcct", account.getAcct());
|
||||
startService(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Task in background starts here.
|
||||
*/
|
||||
private void callAsynchronousTask(final Account account) {
|
||||
//If an Internet connection and user agrees with notification refresh
|
||||
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
//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)
|
||||
return; //Nothing is done
|
||||
//No account connected, the service is stopped
|
||||
if(!Helper.isLoggedIn(getApplicationContext()))
|
||||
return;
|
||||
//If WIFI only and on WIFI OR user defined any connections to use the service.
|
||||
if( isConnectingHashMap.get(account.getAcct()+account.getId()) != null && isConnectingHashMap.get(account.getAcct()+account.getId()))
|
||||
return;
|
||||
if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getApplicationContext())) {
|
||||
Thread readThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
boolean connectionAlive = false;
|
||||
isConnectingHashMap.put(account.getAcct()+account.getId(), true);
|
||||
if( connectionHashMap.get(account.getAcct()+account.getId()) != null) {
|
||||
try {
|
||||
connectionAlive = (connectionHashMap.get(account.getAcct()+account.getId()).getResponseCode() == 200);
|
||||
} catch (Exception e) {
|
||||
connectionAlive = false;
|
||||
}
|
||||
}
|
||||
if( connectionAlive) {
|
||||
HttpsURLConnection httpsURLConnection = connectionHashMap.get(account.getAcct() + account.getId());
|
||||
if( httpsURLConnection != null)
|
||||
httpsURLConnection.disconnect();
|
||||
}
|
||||
try {
|
||||
URL url = new URL("https://" + account.getInstance() + "/api/v1/streaming/user");
|
||||
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
|
||||
urlConnection.setRequestProperty("Content-Type", "application/json");
|
||||
urlConnection.setRequestProperty("Authorization", "Bearer " + account.getToken());
|
||||
urlConnection.setRequestProperty("Connection", "Keep-Alive");
|
||||
urlConnection.setRequestProperty("Keep-Alive", "header");
|
||||
urlConnection.setRequestProperty("Connection", "close");
|
||||
urlConnection.setSSLSocketFactory(new TLSSocketFactory());
|
||||
connectionHashMap.put(account.getAcct()+account.getId(), urlConnection);
|
||||
InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
|
||||
readStream(inputStream, account);
|
||||
} catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
forceRestart(account);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
readThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private String readStream(InputStream inputStream, final Account account) {
|
||||
BufferedReader reader = null;
|
||||
try{
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
String event;
|
||||
EventStreaming eventStreaming = null;
|
||||
//noinspection InfiniteLoopStatement
|
||||
while(true){
|
||||
try {
|
||||
event = reader.readLine();
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
forceRestart(account);
|
||||
break;
|
||||
}
|
||||
if (event !=null){
|
||||
if( (lastEvent == EventStreaming.NONE || lastEvent == null) && !event.startsWith("data: ")) {
|
||||
switch (event.trim()) {
|
||||
case "event: update":
|
||||
lastEvent = EventStreaming.UPDATE;
|
||||
break;
|
||||
case "event: notification":
|
||||
lastEvent = EventStreaming.NOTIFICATION;
|
||||
break;
|
||||
case "event: delete":
|
||||
lastEvent = EventStreaming.DELETE;
|
||||
break;
|
||||
default:
|
||||
lastEvent = EventStreaming.NONE;
|
||||
}
|
||||
}else{
|
||||
if( !event.startsWith("data: ")){
|
||||
lastEvent = EventStreaming.NONE;
|
||||
continue;
|
||||
}
|
||||
event = event.substring(6);
|
||||
if(lastEvent == EventStreaming.UPDATE) {
|
||||
eventStreaming = EventStreaming.UPDATE;
|
||||
}else if(lastEvent == EventStreaming.NOTIFICATION) {
|
||||
eventStreaming = EventStreaming.NOTIFICATION;
|
||||
}else if( lastEvent == EventStreaming.DELETE) {
|
||||
eventStreaming = EventStreaming.DELETE;
|
||||
event = "{id:" + event + "}";
|
||||
}else {
|
||||
eventStreaming = EventStreaming.UPDATE;
|
||||
}
|
||||
lastEvent = EventStreaming.NONE;
|
||||
try {
|
||||
JSONObject eventJson = new JSONObject(event);
|
||||
onRetrieveStreaming(eventStreaming, eventJson, account.getAcct(), account.getId());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
if(reader != null){
|
||||
try{
|
||||
reader.close();
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
forceRestart(account);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void forceRestart(Account account){
|
||||
isConnectingHashMap.put(account.getAcct()+account.getId(), false);
|
||||
SystemClock.sleep(1000);
|
||||
Intent intent = new Intent(getApplicationContext(), StreamingService.class);
|
||||
intent.putExtra("accountId", account.getId());
|
||||
intent.putExtra("accountAcct", account.getAcct());
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskRemoved(Intent rootIntent) {
|
||||
Intent intent = new Intent(getApplicationContext(), StreamingService.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
alarmManager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent);
|
||||
super.onTaskRemoved(rootIntent);
|
||||
}
|
||||
|
||||
|
||||
public void onRetrieveStreaming(EventStreaming event, JSONObject response, String acct, String userId) {
|
||||
if( response == null )
|
||||
return;
|
||||
final SharedPreferences sharedpreferences = 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);
|
||||
|
||||
//No previous notifications in cache, so no notification will be sent
|
||||
boolean notify = false;
|
||||
String notificationUrl = null;
|
||||
String title = null;
|
||||
Status status = null;
|
||||
Notification notification = null;
|
||||
String dataId = null;
|
||||
if( event == EventStreaming.NOTIFICATION){
|
||||
notification = API.parseNotificationResponse(getApplicationContext(), response);
|
||||
switch (notification.getType()){
|
||||
case "mention":
|
||||
if(notif_mention){
|
||||
lastPreviousContent = notification.getStatus().getContent();
|
||||
notify = true;
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
|
||||
title = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_mention));
|
||||
else
|
||||
title = String.format("%s %s", notification.getAccount().getUsername(),getString(R.string.notif_mention));
|
||||
}
|
||||
break;
|
||||
case "reblog":
|
||||
if(notif_share){
|
||||
notify = true;
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
|
||||
title = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_reblog));
|
||||
else
|
||||
title = String.format("%s %s", notification.getAccount().getUsername(),getString(R.string.notif_reblog));
|
||||
}
|
||||
break;
|
||||
case "favourite":
|
||||
if(notif_add){
|
||||
notify = true;
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
|
||||
title = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_favourite));
|
||||
else
|
||||
title = String.format("%s %s", notification.getAccount().getUsername(),getString(R.string.notif_favourite));
|
||||
}
|
||||
break;
|
||||
case "follow":
|
||||
if(notif_follow){
|
||||
notify = true;
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
|
||||
title = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_follow));
|
||||
else
|
||||
title = String.format("%s %s", notification.getAccount().getUsername(),getString(R.string.notif_follow));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Helper.cacheNotifications(getApplicationContext(), notification, userId);
|
||||
if( notification.getStatus().getContent()!= null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
message = Html.fromHtml(notification.getStatus().getContent(), Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
//noinspection deprecation
|
||||
message = Html.fromHtml(notification.getStatus().getContent()).toString();
|
||||
message = message.substring(0, message.length()>49?49:message.length());
|
||||
message = message + "…";
|
||||
}else{
|
||||
message = "";
|
||||
}
|
||||
|
||||
}else if ( event == EventStreaming.UPDATE){
|
||||
status = API.parseStatuses(getApplicationContext(), response);
|
||||
status.setReplies(new ArrayList<Status>()); //Force to don't display replies
|
||||
status.setNew(true);
|
||||
Helper.cacheStatus(getApplicationContext(), status, userId);
|
||||
if( status.getContent() != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
message = Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
//noinspection deprecation
|
||||
message = Html.fromHtml(status.getContent()).toString();
|
||||
message = message.substring(0, message.length()>49?49:message.length());
|
||||
message = message + "…";
|
||||
}else{
|
||||
message = "";
|
||||
}
|
||||
title = getString(R.string.notif_pouet, status.getAccount().getUsername());
|
||||
notificationUrl = status.getAccount().getAvatar();
|
||||
}else if( event == EventStreaming.DELETE){
|
||||
try {
|
||||
dataId = response.getString("id");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//Check which user is connected and if activity is to front
|
||||
boolean activityVisible = false;
|
||||
try{
|
||||
activityVisible = MainActivity.isActivityVisible();
|
||||
}catch (Exception ignored){}
|
||||
String connectedUser = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(connectedUser);
|
||||
//User receiving the notification is connected
|
||||
if( isCurrentAccountLoggedIn(acct, userId)){
|
||||
notify = false;
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_DATA);
|
||||
intentBC.putExtra("eventStreaming", event);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentBC);
|
||||
}
|
||||
//User receiving the notification is connected and application is to front, notification won't be pushed
|
||||
//Instead, the interaction is done in the activity
|
||||
if( activityVisible && isCurrentAccountLoggedIn(acct, userId)){
|
||||
notify = false;
|
||||
}else if(event == EventStreaming.NOTIFICATION ){
|
||||
notify = true;
|
||||
}else if(event == EventStreaming.UPDATE ){
|
||||
//lastPreviousContent contains the content of the last notification, if it was a mention it will avoid to push two notifications
|
||||
if( account == null || (lastPreviousContent != null && lastPreviousContent.equals(status.getContent()))) {
|
||||
notify = false;
|
||||
}else {
|
||||
notify = true;
|
||||
//Retrieve users in db that owner has, and if the toot matches one of them we don't notify
|
||||
List<Account> accounts = new AccountDAO(getApplicationContext(),db).getAllAccount();
|
||||
for(Account act_tmp: accounts) {
|
||||
if(notify && act_tmp.getAcct().trim().equals(status.getAccount().getAcct()) && act_tmp.getId().trim().equals(status.getAccount().getId().trim())){
|
||||
notify = false;
|
||||
}
|
||||
}
|
||||
//Here we check if the user wants home timeline notifications
|
||||
if( notify )
|
||||
notify = sharedpreferences.getBoolean(Helper.SET_NOTIF_HOMETIMELINE, true);
|
||||
}
|
||||
lastPreviousContent = status.getContent();
|
||||
}
|
||||
//All is good here for a notification, we will know check if it can be done depending of the hour
|
||||
if( notify)
|
||||
notify = canNotify(getApplicationContext());
|
||||
if( notify && event == EventStreaming.NOTIFICATION){
|
||||
intent = new Intent(getApplicationContext(), MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
|
||||
intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT);
|
||||
intent.putExtra(PREF_KEY_ID, userId);
|
||||
long notif_id = Long.parseLong(userId);
|
||||
notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notification.getId());
|
||||
editor.apply();
|
||||
}
|
||||
if( notify && event == EventStreaming.UPDATE) {
|
||||
intent = new Intent(getApplicationContext(), MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(INTENT_ACTION, HOME_TIMELINE_INTENT);
|
||||
intent.putExtra(PREF_KEY_ID, userId);
|
||||
long notif_id = Long.parseLong(userId);
|
||||
notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, status.getId());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
if( notify){
|
||||
if( notificationUrl != null){
|
||||
ImageLoader imageLoaderNoty = ImageLoader.getInstance();
|
||||
File cacheDir = new File(getApplicationContext().getCacheDir(), getString(R.string.app_name));
|
||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
|
||||
.imageDownloader(new PatchBaseImageDownloader(getApplicationContext()))
|
||||
.threadPoolSize(5)
|
||||
.threadPriority(Thread.MIN_PRIORITY + 3)
|
||||
.denyCacheImageMultipleSizesInMemory()
|
||||
.diskCache(new UnlimitedDiskCache(cacheDir))
|
||||
.build();
|
||||
imageLoaderNoty.init(config);
|
||||
DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||
|
||||
final String finalTitle = title;
|
||||
imageLoaderNoty.loadImage(notificationUrl, options, new SimpleImageLoadingListener(){
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||
super.onLoadingComplete(imageUri, view, loadedImage);
|
||||
notify_user(getApplicationContext(), intent, notificationId, loadedImage, finalTitle, message);
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason){
|
||||
notify_user(getApplicationContext(), intent, notificationId, BitmapFactory.decodeResource(getApplicationContext().getResources(),
|
||||
R.drawable.mastodonlogo), finalTitle, message);
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCurrentAccountLoggedIn(String acct, String userId){
|
||||
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userconnected = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(userconnected);
|
||||
return acct.trim().equals(account.getAcct().trim()) && userId.trim().equals(account.getId().trim());
|
||||
}
|
||||
}
|
|
@ -133,6 +133,21 @@ public class AccountDAO {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Account by its id and acct
|
||||
* @param accountId String
|
||||
* @param accountAcct String
|
||||
* @return Account
|
||||
*/
|
||||
public Account getAccountByIDAcct(String accountId, String accountAcct){
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_USER_ACCOUNT, null, Sqlite.COL_USER_ID + " = '" + accountId + "' AND " + Sqlite.COL_ACCT + " = '" + accountAcct + "'", null, null, null, null, "1");
|
||||
return cursorToUser(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Account by id and instance
|
||||
* @param accountId String
|
||||
|
|
After Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 284 B |
After Width: | Height: | Size: 939 B |
After Width: | Height: | Size: 939 B |
After Width: | Height: | Size: 514 B |
After Width: | Height: | Size: 514 B |
After Width: | Height: | Size: 253 B |
After Width: | Height: | Size: 452 B |
After Width: | Height: | Size: 452 B |
After Width: | Height: | Size: 298 B |
After Width: | Height: | Size: 556 B |
After Width: | Height: | Size: 556 B |
After Width: | Height: | Size: 360 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 606 B |
After Width: | Height: | Size: 606 B |
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 602 B |
After Width: | Height: | Size: 602 B |
After Width: | Height: | Size: 312 B |
After Width: | Height: | Size: 214 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 324 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 502 B |
After Width: | Height: | Size: 270 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 460 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 304 B |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 490 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1008 B After Width: | Height: | Size: 1008 B |
|
@ -16,9 +16,9 @@
|
|||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<!-- About app name -->
|
||||
<TextView
|
||||
|
@ -40,40 +40,49 @@
|
|||
android:layout_height="wrap_content" />
|
||||
|
||||
<!-- About developer -->
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="20dp"
|
||||
android:gravity="center"
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="5dp"
|
||||
android:text="@string/about_developer"
|
||||
android:textColor="@color/mastodonC4"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<fr.gouv.etalab.mastodon.helper.ExpandableHeightListView
|
||||
android:id="@+id/lv_developers"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:textSize="18sp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:clickable="true"
|
||||
android:layout_width="200dp"
|
||||
android:text="@string/about_developer"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:id="@+id/about_developer"
|
||||
android:text="@string/about_developer_action"
|
||||
android:layout_width="150dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginLeft="150dp"
|
||||
android:layout_marginRight="150dp"
|
||||
android:divider="@null"
|
||||
android:scrollbars="none"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_thanks_dev"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="5dp"
|
||||
android:text="@string/thanks_text_dev"
|
||||
android:textColor="@color/mastodonC4"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<fr.gouv.etalab.mastodon.helper.ExpandableHeightListView
|
||||
android:id="@+id/lv_contributors"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/about_thanks_dev"
|
||||
android:text="@string/thanks_text_dev"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginLeft="150dp"
|
||||
android:layout_marginRight="150dp"
|
||||
android:divider="@null"
|
||||
android:scrollbars="none"/>
|
||||
|
||||
<!-- About license -->
|
||||
<LinearLayout
|
||||
|
@ -89,12 +98,13 @@
|
|||
android:gravity="center"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_license"
|
||||
android:text="@string/about_license_action"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="165dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_license_action"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- About license -->
|
||||
|
@ -111,12 +121,13 @@
|
|||
android:gravity="center"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_code"
|
||||
android:text="@string/about_code_action"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="165dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_code_action"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
@ -136,12 +147,13 @@
|
|||
android:layout_width="200dp"
|
||||
android:text="@string/about_thekinrar"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_thekinrar"
|
||||
android:text="@string/about_thekinrar_action"
|
||||
android:layout_width="150dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="165dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_thekinrar_action"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- About translation -->
|
||||
|
@ -158,12 +170,13 @@
|
|||
android:gravity="center"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_translation"
|
||||
android:text="@string/about_yandex_action"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="165dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_yandex_action"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
|
|
|
@ -68,16 +68,32 @@
|
|||
android:maxLines="1"
|
||||
android:textSize="16sp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textColor="?attr/color_in_account_header"
|
||||
android:id="@+id/account_un"
|
||||
android:maxLines="1"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textColor="?attr/color_in_account_header"
|
||||
android:id="@+id/account_un"
|
||||
android:maxLines="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:gravity="center_horizontal|bottom"
|
||||
android:src="@drawable/ic_action_edit"
|
||||
android:id="@+id/header_edit_profile"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -40,6 +40,12 @@
|
|||
android:text="@string/set_share_validation"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_share_validation_fav"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/set_share_validation_fav"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_show_error_messages"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -58,11 +64,6 @@
|
|||
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"
|
||||
|
@ -70,6 +71,17 @@
|
|||
android:text="@string/set_preview_reply"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_display_local"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/set_display_local"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_display_global"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/set_display_global"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/set_preview_reply_pp_container"
|
||||
|
@ -94,6 +106,24 @@
|
|||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- TABS Layout -->
|
||||
<LinearLayout
|
||||
android:id="@+id/translation_layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_yandex"/>
|
||||
<Spinner
|
||||
android:id="@+id/translation_layout_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -138,25 +168,7 @@
|
|||
android:layout_height="wrap_content" />
|
||||
|
||||
|
||||
<!-- TABS Layout -->
|
||||
<LinearLayout
|
||||
android:id="@+id/translation_layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_yandex"/>
|
||||
<Spinner
|
||||
android:id="@+id/translation_layout_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/set_javascript_container"
|
||||
|
|
|
@ -15,172 +15,188 @@
|
|||
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"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<!-- About app name -->
|
||||
<TextView
|
||||
android:layout_marginTop="20dp"
|
||||
android:textSize="20sp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/app_name"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<!-- About version -->
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:id="@+id/about_version"
|
||||
android:textSize="16sp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<!-- About developer -->
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<!-- About app name -->
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:textSize="20sp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/app_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<!-- About version -->
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:id="@+id/about_version"
|
||||
android:textSize="16sp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<!-- About developer -->
|
||||
<TextView
|
||||
android:padding="5dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:clickable="true"
|
||||
android:layout_weight="2"
|
||||
android:layout_width="0dp"
|
||||
android:textColor="@color/mastodonC4"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/about_developer"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:id="@+id/about_developer"
|
||||
android:text="@string/about_developer_action"
|
||||
android:layout_weight="3"
|
||||
android:layout_width="0dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
android:textSize="16sp"/>
|
||||
<fr.gouv.etalab.mastodon.helper.ExpandableHeightListView
|
||||
android:id="@+id/lv_developers"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:divider="@null"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:padding="5dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:id="@+id/about_thanks_dev"
|
||||
android:text="@string/thanks_text_dev"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- About license -->
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:text="@string/about_license"
|
||||
android:textColor="@color/mastodonC4"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:layout_weight="2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:id="@+id/about_license"
|
||||
android:text="@string/about_license_action"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_weight="3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
android:text="@string/thanks_text_dev"/>
|
||||
|
||||
<!-- About license -->
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:text="@string/about_code"
|
||||
android:textSize="16sp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:layout_weight="2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:id="@+id/about_code"
|
||||
android:text="@string/about_code_action"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_weight="3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<!-- About The Kinrar's API -->
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:textSize="16sp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:clickable="true"
|
||||
android:layout_weight="2"
|
||||
android:layout_width="0dp"
|
||||
android:text="@string/about_thekinrar"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:id="@+id/about_thekinrar"
|
||||
android:text="@string/about_thekinrar_action"
|
||||
android:layout_weight="3"
|
||||
android:layout_width="0dp"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- About translation -->
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:text="@string/about_yandex"
|
||||
android:textSize="16sp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:layout_weight="2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:id="@+id/about_translation"
|
||||
android:text="@string/about_yandex_action"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_weight="3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:text="@string/thanks_text"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center_horizontal"
|
||||
<fr.gouv.etalab.mastodon.helper.ExpandableHeightListView
|
||||
android:id="@+id/lv_contributors"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:divider="@null"/>
|
||||
|
||||
<!-- About license -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="2"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_license"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_license"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
android:text="@string/about_license_action"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- About license -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="2"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_code"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_code"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
android:text="@string/about_code_action"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<!-- About The Kinrar's API -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="2"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_thekinrar"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_thekinrar"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
android:text="@string/about_thekinrar_action"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- About translation -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="2"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_yandex"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/about_translation"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
android:text="@string/about_yandex_action"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/thanks_text"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -68,16 +68,32 @@
|
|||
android:maxLines="1"
|
||||
android:textSize="16sp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textColor="?attr/color_in_account_header"
|
||||
android:id="@+id/account_un"
|
||||
android:maxLines="1"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textColor="?attr/color_in_account_header"
|
||||
android:id="@+id/account_un"
|
||||
android:maxLines="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:gravity="center_horizontal|bottom"
|
||||
android:src="@drawable/ic_action_edit"
|
||||
android:id="@+id/header_edit_profile"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?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>.
|
||||
-->
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:card_view="http://schemas.android.com/tools"
|
||||
style="?attr/cardStyle"
|
||||
android:layout_marginTop="10dp"
|
||||
card_view:cardPreventCornerOverlap="true"
|
||||
app:cardUseCompatPadding="true">
|
||||
<LinearLayout
|
||||
android:id="@+id/acccount_container"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
<ImageView
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:id="@+id/account_pp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
<LinearLayout
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/account_dn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||
<TextView
|
||||
android:id="@+id/account_un"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:layout_gravity="center"
|
||||
app:fabSize="mini"
|
||||
android:id="@+id/account_follow"
|
||||
android:textAllCaps="false"
|
||||
android:src="@drawable/ic_user_plus"
|
||||
android:gravity="center"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</android.support.v7.widget.CardView>
|
|
@ -35,7 +35,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/main_container"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
card_view:ignore="DisableBaselineAlignment">
|
||||
<LinearLayout
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -71,21 +71,15 @@
|
|||
style="?attr/shapeBorder"
|
||||
android:visibility="gone"
|
||||
tools:ignore="ContentDescription" />
|
||||
<Button
|
||||
android:id="@+id/status_translate"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
<ImageView
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="70dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:scaleType="center"
|
||||
android:drawablePadding="0dp"
|
||||
android:paddingStart="17dp"
|
||||
android:paddingLeft="17dp"
|
||||
android:drawableStart="@drawable/ic_translate"
|
||||
android:drawableLeft="@drawable/ic_translate"
|
||||
android:id="@+id/new_element"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/ic_fiber_new"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="ContentDescription" />
|
||||
</RelativeLayout>
|
||||
<LinearLayout
|
||||
|
@ -196,6 +190,14 @@
|
|||
android:text="Powered by Yandex.Translate"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="HardcodedText" />
|
||||
<TextView
|
||||
android:id="@+id/google_translate"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="2dp"
|
||||
android:gravity="end"
|
||||
android:text="Powered by Google Translate"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -330,11 +332,22 @@
|
|||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:text="@string/translate_toot"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical|end"
|
||||
android:id="@+id/status_translate"
|
||||
android:textColor="@color/mastodonC4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<LinearLayout
|
||||
android:id="@+id/status_action_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:padding="@dimen/drawer_padding"
|
||||
android:layout_marginStart="@dimen/activity_vertical_margin"
|
||||
android:layout_marginLeft="@dimen/activity_vertical_margin"
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?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>.
|
||||
-->
|
||||
<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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="?attr/popupOverlay">
|
||||
<ImageView
|
||||
android:id="@+id/close_conversation"
|
||||
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" />
|
||||
<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="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/actionBarTextColor"
|
||||
android:textSize="14sp"
|
||||
android:id="@+id/toolbar_title" />
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
|
@ -40,6 +40,12 @@
|
|||
android:text="@string/set_share_validation"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_share_validation_fav"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/set_share_validation_fav"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_show_error_messages"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -58,11 +64,6 @@
|
|||
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"
|
||||
|
@ -70,6 +71,18 @@
|
|||
android:text="@string/set_preview_reply"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_display_local"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/set_display_local"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/set_display_global"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/set_display_global"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/set_preview_reply_pp_container"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -93,7 +106,24 @@
|
|||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<!-- Translation engine -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="10dp"
|
||||
android:id="@+id/translation_layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_yandex"/>
|
||||
<Spinner
|
||||
android:id="@+id/translation_layout_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -139,25 +169,7 @@
|
|||
|
||||
|
||||
|
||||
<!-- Translation engine -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:id="@+id/translation_layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_yandex"/>
|
||||
<Spinner
|
||||
android:id="@+id/translation_layout_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/set_javascript_container"
|
||||
|
|
|
@ -173,6 +173,25 @@
|
|||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/set_led_colour_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:text="@string/set_led_colour"/>
|
||||
<Spinner
|
||||
android:id="@+id/led_colour_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/led_colours"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
|
|