Merge remote-tracking branch 'tom-repo/develop' into PhotonQyv-Baseline

This commit is contained in:
PhotonQyv 2017-09-03 09:53:17 +01:00
commit 668fc3bd39
18 changed files with 784 additions and 306 deletions

View File

@ -148,11 +148,8 @@ public class MainActivity extends AppCompatActivity
if(notificationsFragment.getUserVisibleHint() && isActivityVisible()){
notificationsFragment.updateData(notification);
}else{
updateNotifCounter();
notificationsFragment.refresh(notification);
}
}else {
updateNotifCounter();
}
}else if(eventStreaming == StreamingService.EventStreaming.UPDATE){
Status status = b.getParcelable("data");
@ -160,11 +157,8 @@ public class MainActivity extends AppCompatActivity
if(homeFragment.getUserVisibleHint() && isActivityVisible()){
homeFragment.updateData(status);
}else{
updateHomeCounter();
homeFragment.refresh(status);
}
}else{
updateHomeCounter();
}
}else if(eventStreaming == StreamingService.EventStreaming.DELETE){
String id = b.getString("id");
@ -176,6 +170,8 @@ public class MainActivity extends AppCompatActivity
}
}
}
updateNotifCounter();
updateHomeCounter();
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
@ -868,6 +864,8 @@ public class MainActivity extends AppCompatActivity
public void onResume(){
super.onResume();
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);

View File

@ -23,23 +23,28 @@ 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.MotionEvent;
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 +53,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 +81,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 +102,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 +119,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 +148,99 @@ 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, int statusCount, int followingCount, int 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(statusCount);
account.setFollowers_count(followersCount);
account.setFollowing_count(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 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( developers.get(i).getId().equals(relationship.getId()) && relationship.isFollowing() || userId.trim().equals(relationship.getId())){
developers.get(i).setFollowing(true);
accountSearchWebAdapterDeveloper.notifyDataSetChanged();
}
}
for( int i = 0 ; i < contributors.size() ; i++){
if( contributors.get(i).getId().equals(relationship.getId()) && relationship.isFollowing() || userId.trim().equals(relationship.getId())){
contributors.get(i).setFollowing(true);
accountSearchWebAdapterContributors.notifyDataSetChanged();
}
}
}
}

View File

@ -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, int statusCount, int followingCount, int followersCount) {
loader.setVisibility(View.GONE);
rf_search.setEnabled(true);
if( error){

View File

@ -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);
}
}

View File

@ -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;
@ -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 = Integer.parseInt(countElement.get(0).html().replace(",",""));
followingCount = Integer.parseInt(countElement.get(1).html().replace(",",""));
followersCount = Integer.parseInt(countElement.get(2).html().replace(",",""));
} 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);
}
}

View File

@ -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(context, 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*
*

View File

@ -43,6 +43,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 +239,20 @@ 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;
}
}

View File

@ -0,0 +1,206 @@
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;
}
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;
}
}

View File

@ -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;
}
}

View File

@ -18,6 +18,7 @@ package fr.gouv.etalab.mastodon.helper;
import android.app.Activity;
import android.preference.PreferenceManager;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AlertDialog;
import android.app.DownloadManager;
@ -81,6 +82,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;
@ -102,11 +104,13 @@ 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;
@ -203,8 +207,10 @@ public class Helper {
public static final String SET_PREVIEW_REPLIES_PP = "set_preview_replies_pp";
public static final String SET_TRANSLATOR = "set_translator";
public static final String SET_LED_COLOUR = "set_led_colour";
public static final String SET_UNREAD_NOTIFICATIONS = "set_unread_notifications";
public static final String SET_UNREAD_TOOTS = "set_unread_toots";
private static final String SET_UNREAD_NOTIFICATIONS = "set_unread_notifications";
private static final String SET_UNREAD_TOOTS = "set_unread_toots";
private static final String SET_DEVELOPERS = "set_developers";
private static final String SET_DEVELOPERS_CACHE_DATE = "set_developers_cache_date";
public static final int ATTACHMENT_ALWAYS = 1;
public static final int ATTACHMENT_WIFI = 2;
@ -1672,4 +1678,31 @@ public class Helper {
editor.apply();
}
}
public static String[] developers = {
"https://mastodon.etalab.gouv.fr/@tschneider",
"https://mastodon.xyz/@PhotonQyv",
"https://social.tchncs.de/@angrytux"
};
public static void cacheDevelopers(Context context, ArrayList<Account> accounts){
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
Gson gson = new Gson();
String serializedAccounts = gson.toJson(accounts);
editor.putString(Helper.SET_DEVELOPERS, serializedAccounts);
editor.putString(Helper.SET_DEVELOPERS_CACHE_DATE, dateToString(context, new Date()));
editor.apply();
}
public static ArrayList<Account> getDevelopers(Context context){
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedpreferences.getString(Helper.SET_DEVELOPERS, null);
Type type = new TypeToken<ArrayList<Account>>() {}.getType();
return gson.fromJson(json, type);
}
}

View File

@ -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, int statusCount, int followingCount, int followersCount);
}

View File

@ -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);
}

View File

@ -40,40 +40,42 @@
android:layout_height="wrap_content" />
<!-- About developer -->
<LinearLayout
android:orientation="horizontal"
android:padding="20dp"
android:gravity="center"
<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:textColor="@color/mastodonC4"
android:gravity="center_vertical"
android:text="@string/about_developer"
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:scrollbars="none"
android:divider="@null"/>
<TextView
android:padding="5dp"
android:layout_marginTop="10dp"
android:id="@+id/about_thanks_dev"
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:textColor="@color/mastodonC4"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:textSize="16sp"
android:text="@string/thanks_text_dev"/>
<fr.gouv.etalab.mastodon.helper.ExpandableHeightListView
android:id="@+id/lv_contributors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:divider="@null"/>
<!-- About license -->
<LinearLayout

View File

@ -15,186 +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="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_horizontal"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- About developer -->
<LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
android:orientation="vertical"
>
<!-- About app name -->
<TextView
android:layout_width="0dp"
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_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"
android:layout_weight="2"
android:layout_gravity="center_vertical"
android:clickable="true"
android:gravity="center"
android:textColor="@color/mastodonC4"
android:gravity="center_vertical"
android:text="@string/about_developer"
android:textSize="16sp"/>
<Button
android:id="@+id/about_developer"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="0dp"
<fr.gouv.etalab.mastodon.helper.ExpandableHeightListView
android:id="@+id/lv_developers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="@string/about_developer_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">
android:scrollbars="none"
android:divider="@null"/>
<TextView
android:padding="5dp"
android:layout_marginTop="10dp"
android:id="@+id/about_thanks_dev"
android:layout_width="match_parent"
android:textColor="@color/mastodonC4"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:textSize="16sp"
android:text="@string/thanks_text_dev"/>
</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_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
<fr.gouv.etalab.mastodon.helper.ExpandableHeightListView
android:id="@+id/lv_contributors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/thanks_text"/>
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>

View File

@ -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>

View File

@ -422,7 +422,7 @@
<string name="thanks_text">Danke an Stéphane für das Logo.</string>
<string name="thanks_text_dev">
Danke an @PhotonQyv für seine Beiträge.
Danke an:
</string>
<string name="new_data">Neue Daten verfügbar sind! Wollen Sie Sie anzeigen?</string>
<string name="set_bubble_counter">Display-Zähler</string>

View File

@ -421,6 +421,6 @@
</string>
<string name="thanks_text_dev">
Merci à @PhotonQyv pour ses contributions.
Merci à :
</string>
</resources>

View File

@ -430,6 +430,6 @@
</string>
<string name="thanks_text_dev">
Thank you to @PhotonQyv for his contributions.
Thank you to:
</string>
</resources>