diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8a0bfa1ae..99b9a48f4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -80,6 +80,11 @@
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
/>
+
accounts, Error error) {
+ about_developer.setEnabled(true);
+ 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);
+ }
+ });
+ }
+ }
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java
index 27fc0ddb2..d3fab022f 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java
@@ -24,6 +24,8 @@ import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
@@ -87,6 +89,19 @@ public class LoginActivity extends AppCompatActivity {
}
});
+ //For other instances
+ TextView other_instance = (TextView) findViewById(R.id.other_instance);
+ other_instance.setPaintFlags(other_instance.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
+ other_instance.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(LoginActivity.this, LoginActivity.class);
+ intent.putExtra("addAccount", true);
+ startActivity(intent);
+ finish();
+ }
+ });
+
Bundle b = getIntent().getExtras();
if(b != null)
addAccount = b.getBoolean("addAccount", false);
@@ -106,6 +121,8 @@ public class LoginActivity extends AppCompatActivity {
}
});
}
+ if( addAccount)
+ other_instance.setVisibility(View.GONE);
}
@Override
@@ -199,7 +216,9 @@ public class LoginActivity extends AppCompatActivity {
requestParams.add("scope"," read write follow");
client.setUserAgent(USER_AGENT);
try {
- client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore()));
+ MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
+ mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.post("https://" + instance+ "/oauth/token", requestParams, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
@@ -236,6 +255,29 @@ public class LoginActivity extends AppCompatActivity {
}
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main_login, menu);
+ return true;
+ }
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_about) {
+ Intent intent = new Intent(getApplicationContext(), AboutActivity.class);
+ startActivity(intent);
+ }else if(id == R.id.action_privacy){
+ Intent intent = new Intent(getApplicationContext(), PrivacyActivity.class);
+ startActivity(intent);
+ }
+ return super.onOptionsItemSelected(item);
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainActivity.java
index e7c143e0e..ec6f329f6 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainActivity.java
@@ -282,6 +282,9 @@ public class MainActivity extends AppCompatActivity
}else if(id == R.id.action_about){
Intent intent = new Intent(getApplicationContext(), AboutActivity.class);
startActivity(intent);
+ }else if(id == R.id.action_privacy){
+ Intent intent = new Intent(getApplicationContext(), PrivacyActivity.class);
+ startActivity(intent);
}else if(id == R.id.action_search){
if( toolbar.getChildCount() > 0){
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/PrivacyActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/PrivacyActivity.java
new file mode 100644
index 000000000..223aad6e4
--- /dev/null
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/PrivacyActivity.java
@@ -0,0 +1,49 @@
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr
+ *
+ * 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.
+ *
+ * Mastodon Etalab 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 Thomas Schneider; if not,
+ * see . */
+package fr.gouv.etalab.mastodon.activities;
+
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.MenuItem;
+import mastodon.etalab.gouv.fr.mastodon.R;
+
+
+/**
+ * Created by Thomas on 03/06/2017.
+ * Privacy activity
+ */
+
+public class PrivacyActivity extends AppCompatActivity {
+ @SuppressWarnings("deprecation")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if( getSupportActionBar() != null)
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ setContentView(R.layout.activity_privacy);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowAccountActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowAccountActivity.java
index f85233d58..69df1ec6b 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowAccountActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowAccountActivity.java
@@ -105,9 +105,6 @@ public class ShowAccountActivity extends AppCompatActivity implements OnPostActi
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_account);
-
-
-
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
imageLoader = ImageLoader.getInstance();
statuses = new ArrayList<>();
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveDeveloperAccountsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveDeveloperAccountsAsyncTask.java
new file mode 100644
index 000000000..d1f9fa0c2
--- /dev/null
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveDeveloperAccountsAsyncTask.java
@@ -0,0 +1,53 @@
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr
+ *
+ * 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.
+ *
+ * Mastodon Etalab 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 Thomas Schneider; if not,
+ * see . */
+package fr.gouv.etalab.mastodon.asynctasks;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import java.util.List;
+import fr.gouv.etalab.mastodon.client.API;
+import fr.gouv.etalab.mastodon.client.Entities.Account;
+import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
+
+
+/**
+ * Created by Thomas on 03/06/2017.
+ * Retrieves developer from search (ie: starting with @ when writing a toot)
+ */
+
+public class RetrieveDeveloperAccountsAsyncTask extends AsyncTask {
+
+ private Context context;
+ private List accounts;
+ private OnRetrieveSearcAccountshInterface listener;
+ private API api;
+
+ public RetrieveDeveloperAccountsAsyncTask(Context context, OnRetrieveSearcAccountshInterface onRetrieveSearcAccountshInterface){
+ this.context = context;
+ this.listener = onRetrieveSearcAccountshInterface;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ api = new API(context);
+ accounts = api.searchDeveloper();
+ return null;
+ }
+ @Override
+ protected void onPostExecute(Void result) {
+ listener.onRetrieveSearchAccounts(accounts, api.getError());
+ }
+
+}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
index 7e6b06ddc..e1083a81f 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
@@ -850,6 +850,32 @@ public class API {
return results;
}
+ /**
+ * Retrieves Developer account when searching (ie: via @...) *synchronously*
+ *
+ * @return List
+ */
+ public List 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);
+ }
+ @Override
+ public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
+ accounts = parseDeveloperResponse(response);
+ }
+ @Override
+ public void onFailure(int statusCode, Header[] headers, Throwable error, JSONObject response){
+ setError(statusCode, error);
+ }
+ });
+ return accounts;
+ }
/**
* Retrieves Accounts when searching (ie: via @...) *synchronously*
*
@@ -926,60 +952,10 @@ public class API {
try {
int i = 0;
while (i < jsonArray.length() ){
- Status status = new Status();
+
JSONObject resobj = jsonArray.getJSONObject(i);
- status.setId(resobj.get("id").toString());
- status.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
- status.setIn_reply_to_id(resobj.get("in_reply_to_id").toString());
- status.setIn_reply_to_account_id(resobj.get("in_reply_to_account_id").toString());
- status.setSensitive(Boolean.getBoolean(resobj.get("sensitive").toString()));
- status.setSpoiler_text(resobj.get("spoiler_text").toString());
- status.setVisibility(resobj.get("visibility").toString());
-
- //TODO: replace by the value
- status.setApplication(new Application());
-
- JSONArray arrayAttachement = resobj.getJSONArray("media_attachments");
- List attachments = new ArrayList<>();
- if( arrayAttachement != null){
- for(int j = 0 ; j < arrayAttachement.length() ; j++){
- JSONObject attObj = arrayAttachement.getJSONObject(j);
- Attachment attachment = new Attachment();
- attachment.setId(attObj.get("id").toString());
- attachment.setPreview_url(attObj.get("preview_url").toString());
- attachment.setRemote_url(attObj.get("remote_url").toString());
- attachment.setType(attObj.get("type").toString());
- attachment.setText_url(attObj.get("text_url").toString());
- attachment.setUrl(attObj.get("url").toString());
- attachments.add(attachment);
- }
- }
- List mentions = new ArrayList<>();
- JSONArray arrayMention = resobj.getJSONArray("mentions");
- if( arrayMention != null){
- for(int j = 0 ; j < arrayMention.length() ; j++){
- JSONObject menObj = arrayMention.getJSONObject(j);
- Mention mention = new Mention();
- mention.setId(menObj.get("id").toString());
- mention.setUrl(menObj.get("url").toString());
- mention.setAcct(menObj.get("acct").toString());
- mention.setUsername(menObj.get("username").toString());
- mentions.add(mention);
- }
- }
- status.setMedia_attachments(attachments);
- status.setMentions(mentions);
- status.setAccount(parseAccountResponse(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")));
- }catch (Exception ignored){}
+ Status status = parseStatuses(resobj);
i++;
-
statuses.add(status);
}
@@ -1025,6 +1001,20 @@ public class API {
}
}
status.setMedia_attachments(attachments);
+ List mentions = new ArrayList<>();
+ JSONArray arrayMention = resobj.getJSONArray("mentions");
+ if( arrayMention != null){
+ for(int j = 0 ; j < arrayMention.length() ; j++){
+ JSONObject menObj = arrayMention.getJSONObject(j);
+ Mention mention = new Mention();
+ mention.setId(menObj.get("id").toString());
+ mention.setUrl(menObj.get("url").toString());
+ mention.setAcct(menObj.get("acct").toString());
+ mention.setUsername(menObj.get("username").toString());
+ mentions.add(mention);
+ }
+ }
+ status.setMentions(mentions);
status.setAccount(parseAccountResponse(resobj.getJSONObject("account")));
status.setContent(resobj.get("content").toString());
status.setFavourites_count(Integer.valueOf(resobj.get("favourites_count").toString()));
@@ -1082,23 +1072,8 @@ public class API {
try {
int i = 0;
while (i < jsonArray.length() ) {
- Account account = new Account();
JSONObject resobj = jsonArray.getJSONObject(i);
- account.setId(resobj.get("id").toString());
- account.setUsername(resobj.get("username").toString());
- account.setAcct(resobj.get("acct").toString());
- account.setDisplay_name(resobj.get("display_name").toString());
- account.setLocked(Boolean.parseBoolean(resobj.get("locked").toString()));
- account.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
- account.setFollowers_count(Integer.valueOf(resobj.get("followers_count").toString()));
- account.setFollowing_count(Integer.valueOf(resobj.get("following_count").toString()));
- account.setStatuses_count(Integer.valueOf(resobj.get("statuses_count").toString()));
- account.setNote(resobj.get("note").toString());
- account.setUrl(resobj.get("url").toString());
- account.setAvatar(resobj.get("avatar").toString());
- account.setAvatar_static(resobj.get("avatar_static").toString());
- account.setHeader(resobj.get("header").toString());
- account.setHeader_static(resobj.get("header_static").toString());
+ Account account = parseAccountResponse(resobj);
accounts.add(account);
i++;
}
@@ -1108,6 +1083,33 @@ public class API {
return accounts;
}
+
+ /**
+ * Parse json response for list of accounts which could contain the developer name
+ * @param jsonArray JSONArray
+ * @return List
+ */
+ private List parseDeveloperResponse(JSONArray jsonArray){
+
+ List accounts = new ArrayList<>();
+ try {
+ int i = 0;
+ Account account = null;
+ while (i < jsonArray.length() ) {
+ JSONObject resobj = jsonArray.getJSONObject(i);
+ account = parseAccountResponse(resobj);
+ if( account.getAcct().contains(Helper.INSTANCE))
+ accounts.add(account);
+ i++;
+ }
+ if( accounts.size() == 0)
+ accounts.add(account);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return accounts;
+ }
+
/**
* Parse json response for the context
* @param jsonObject JSONObject
@@ -1208,16 +1210,9 @@ public class API {
try {
int i = 0;
while (i < jsonArray.length() ) {
- Notification notification = new Notification();
+
JSONObject resobj = jsonArray.getJSONObject(i);
- 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")));
- try{
- notification.setStatus(parseStatuses(resobj.getJSONObject("status")));
- }catch (Exception ignored){}
- notification.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
+ Notification notification = parseNotificationResponse(resobj);
notifications.add(notification);
i++;
}
@@ -1246,7 +1241,9 @@ public class API {
client.setConnectTimeout(10000); //10s timeout
client.setUserAgent(USER_AGENT);
client.addHeader("Authorization", "Bearer "+prefKeyOauthTokenT);
- client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore()));
+ MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
+ mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.get(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
@@ -1261,7 +1258,9 @@ public class API {
client.setConnectTimeout(10000); //10s timeout
client.setUserAgent(USER_AGENT);
client.addHeader("Authorization", "Bearer "+prefKeyOauthTokenT);
- client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore()));
+ MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
+ mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.post(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
Toast.makeText(context, R.string.toast_error,Toast.LENGTH_LONG).show();
@@ -1274,7 +1273,9 @@ public class API {
client.setConnectTimeout(10000); //10s timeout
client.setUserAgent(USER_AGENT);
client.addHeader("Authorization", "Bearer "+prefKeyOauthTokenT);
- client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore()));
+ MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
+ mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.delete(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
Toast.makeText(context, R.string.toast_error,Toast.LENGTH_LONG).show();
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java
index 9b5f66c38..00b952c52 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java
@@ -47,7 +47,9 @@ public class OauthClient {
try {
client.setConnectTimeout(10000); //10s timeout
client.setUserAgent(USER_AGENT);
- client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore()));
+ MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
+ mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.get(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
e.printStackTrace();
@@ -58,7 +60,9 @@ public class OauthClient {
try {
client.setConnectTimeout(10000); //10s timeout
client.setUserAgent(USER_AGENT);
- client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore()));
+ MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
+ mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.post(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
e.printStackTrace();
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java
index ce9405c55..b4a8f0640 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java
@@ -16,6 +16,8 @@ package fr.gouv.etalab.mastodon.drawers;
import android.Manifest;
import android.app.AlertDialog;
+import android.content.ClipData;
+import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -32,6 +34,7 @@ import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.Html;
import android.text.util.Linkify;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -437,7 +440,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
final RelativeLayout loader = (RelativeLayout) view.findViewById(R.id.loader);
switch (attachment.getType()){
case "image": {
- String url = attachment.getRemote_url();
+ String url = attachment.getPreview_url();
if(url == null || url.trim().equals(""))
url = attachment.getUrl();
final ImageView imageView = (ImageView) view.findViewById(R.id.dialog_imageview);
@@ -666,20 +669,48 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
AlertDialog.Builder builderInner = new AlertDialog.Builder(context);
builderInner.setTitle(stringArrayConf[which]);
if( isOwner) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
- builderInner.setMessage(Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_COMPACT));
- else
- //noinspection deprecation
- builderInner.setMessage(Html.fromHtml(status.getContent()));
- }else {
- if( which < 2 ){
- builderInner.setMessage(status.getAccount().getAcct());
- }else {
+ if( which == 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
builderInner.setMessage(Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_COMPACT));
else
//noinspection deprecation
builderInner.setMessage(Html.fromHtml(status.getContent()));
+ }else{
+ ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
+ String content;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ content = Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_COMPACT).toString();
+ else
+ //noinspection deprecation
+ content = Html.fromHtml(status.getContent()).toString();
+ ClipData clip = ClipData.newPlainText(Helper.CLIP_BOARD, content);
+ clipboard.setPrimaryClip(clip);
+ Toast.makeText(context,R.string.clipboard,Toast.LENGTH_LONG).show();
+ dialog.dismiss();
+ return;
+ }
+ }else {
+ if( which < 2 ){
+ builderInner.setMessage(status.getAccount().getAcct());
+ }else if( which < 3) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ builderInner.setMessage(Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_COMPACT));
+ else
+ //noinspection deprecation
+ builderInner.setMessage(Html.fromHtml(status.getContent()));
+ }else{
+ ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
+ String content;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ content = Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_COMPACT).toString();
+ else
+ //noinspection deprecation
+ content = Html.fromHtml(status.getContent()).toString();
+ ClipData clip = ClipData.newPlainText(Helper.CLIP_BOARD, content);
+ clipboard.setPrimaryClip(clip);
+ Toast.makeText(context,R.string.clipboard,Toast.LENGTH_LONG).show();
+ dialog.dismiss();
+ return;
}
}
//Text for report
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java
index 5a0e48237..29940bb29 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java
@@ -20,6 +20,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -55,7 +56,7 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
private Context context;
private AsyncTask asyncTask;
private NotificationsListAdapter notificationsListAdapter;
- private String max_id = null;
+ private String max_id;
private List notifications;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
@@ -66,7 +67,7 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_notifications, container, false);
-
+ max_id = null;
context = getContext();
firstLoad = true;
flag_loading = true;
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
index 754bec481..f3bde33d1 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
@@ -110,6 +110,7 @@ public class Helper {
public static final String WEBSITE = "website";
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 CLIP_BOARD = "clipboard";
//Notifications
public static final int NOTIFICATION_INTENT = 1;
public static final int HOME_TIMELINE_INTENT = 2;
@@ -418,6 +419,7 @@ public class Helper {
// prepare intent which is triggered if the user click on the notification
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
PendingIntent pIntent = PendingIntent.getActivity(context, notificationId, intent, PendingIntent.FLAG_ONE_SHOT);
+
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// build notification
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java
index 5f6566078..25b66dcd1 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java
@@ -22,7 +22,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
-import android.widget.Toast;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager;
@@ -64,6 +63,7 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe
static final String HOME_TIMELINE = "home_timeline";
private int notificationId;
+
@NonNull
@Override
protected Result onRunJob(Params params) {
@@ -93,11 +93,17 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe
* Task in background starts here.
*/
private void callAsynchronousTask() {
+
+
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean notif_hometimeline = sharedpreferences.getBoolean(Helper.SET_NOTIF_HOMETIMELINE, true);
+
//User disagree with home timeline refresh
if( !notif_hometimeline)
return; //Nothing is done
+ //No account connected, the service is stopped
+ if(!Helper.isLoggedIn(getContext()))
+ return;
SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
//If an Internet connection and user agrees with notification refresh
//If WIFI only and on WIFI OR user defined any connections to use the service.
@@ -109,7 +115,8 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe
//Retrieve users in db that owner has.
for (Account account: accounts) {
String since_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + account.getId(), null);
- notificationId = (int) Math.round(Double.parseDouble(account.getId())/100) + 2;
+ long notif_id = Long.parseLong(account.getId());
+ notificationId = ((notif_id + 2) > 2147483647 )?(int)(2147483647 - notif_id -2):(int)(notif_id + 2);
new RetrieveHomeTimelineServiceAsyncTask(getContext(), account.getInstance(), account.getToken(), since_id, account.getAcct(), account.getId(), HomeTimelineSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -162,7 +169,9 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe
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);
- notify_user(getContext(), intent, notificationId, icon_notification,title,message);
+
+ if( max_id != null)
+ notify_user(getContext(), intent, notificationId, icon_notification,title,message);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, statuses.get(0).getId());
editor.apply();
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java
index cb3679ade..373ff742e 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java
@@ -22,8 +22,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
-import android.util.Log;
-
import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager;
@@ -110,6 +108,9 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
//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(getContext()))
+ return;
//If WIFI only and on WIFI OR user defined any connections to use the service.
if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getContext())) {
List accounts = new AccountDAO(getContext(),db).getAllAccount();
@@ -119,7 +120,8 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
//Retrieve users in db that owner has.
for (Account account: accounts) {
String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId(), null);
- notificationId = (int) Math.round(Double.parseDouble(account.getId())/100) + 1;
+ long notif_id = Long.parseLong(account.getId());
+ notificationId = ((notif_id + 1) > 2147483647 )?(int)(2147483647 - notif_id - 1):(int)(notif_id + 1);
new RetrieveNotificationsAsyncTask(getContext(), account.getInstance(), account.getToken(), max_id, account.getAcct(), account.getId(), NotificationsSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@@ -221,7 +223,8 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT);
intent.putExtra(PREF_KEY_ID, userId);
- notify_user(getContext(), intent, notificationId, icon_notification,title,message);
+ if( max_id != null)
+ notify_user(getContext(), intent, notificationId, icon_notification,title,message);
}
SharedPreferences.Editor editor = sharedpreferences.edit();
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index 06bfd9422..a402c4f07 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -15,88 +15,96 @@
You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
see .
-->
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_privacy.xml b/app/src/main/res/layout/activity_privacy.xml
new file mode 100644
index 000000000..0302a1cdd
--- /dev/null
+++ b/app/src/main/res/layout/activity_privacy.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
index a13c9b313..3a6e1f684 100644
--- a/app/src/main/res/menu/main.xml
+++ b/app/src/main/res/menu/main.xml
@@ -10,6 +10,10 @@
android:id="@+id/action_about"
android:title="@string/action_about"
app:showAsAction="never" />
+
-
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 472e7dbdb..269b6465e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -6,6 +6,7 @@
Paramètres
A propos
+ Confidentialité
Déconnexion
Connexion
@@ -23,10 +24,12 @@
Pouets
Jeton
Authentification en deux étapes ?
+ Autre instance que mastodon.etalab.gouv.fr ?
Aucun résultat !
Instance
Utilisation du compte %1$s
Ajouter un compte
+ Le contenu du pouet a été copié dans le presse-papier
Accueil
Accueil
@@ -61,15 +64,18 @@
- Masquer
- Bloquer
- Signaler
+ - Copier
- Supprimer
+ - Copier
- Masquer ce compte ?
- Bloquer ce compte ?
- Signaler ce pouet ?
+ - null
@@ -218,6 +224,26 @@
Demande envoyée
Vous suit
-
Recherche
+
+
+
+
+ Autorisations de l\'application
+
+ - ACCESS_NETWORK_STATE : Utilisée pour savoir si l\'appareil est connecté au WIFI.\n
+ - INTERNET : Utilisée pour les requêtes vers l\'instance.\n
+ - WRITE_EXTERNAL_STORAGE : Utilisée pour télécharger les médias / déplacer sur la carte SD.\n
+ - READ_EXTERNAL_STORAGE : Utilisée pour ajouter des médias aux pouets.\n
+ - BOOT_COMPLETED : Utilisée pour lancer le service de notifications quand l\'appareil démarre.\n
+ - WAKE_LOCK : Utilisée lors du service de notifications.\n
+
+
+ Autorisations de l\'API
+
+ - Read : Lire les données du compte.\n
+ - Write : Envoyer des messages et attacher des médias aux messages.\n
+ - Follow : S\'abonner, se désabonner, bloquer, débloquer.\n\n
+ ⚠ Ces actions ne sont réalisées qu\'à la demande de l\'utilisateur.
+