From 7a67b672e8fdfa040a1c5fcbc8022d995a05670f Mon Sep 17 00:00:00 2001 From: tom79 Date: Wed, 8 May 2019 17:50:17 +0200 Subject: [PATCH] Honour media default privacy for accounts + add option in settings --- .../activities/EditProfileActivity.java | 23 ++++++--- .../mastodon/activities/TootActivity.java | 3 ++ .../UpdateAccountInfoAsyncTask.java | 2 +- .../UpdateAccountInfoByIDAsyncTask.java | 4 +- .../asynctasks/UpdateCredentialAsyncTask.java | 6 ++- .../fr/gouv/etalab/mastodon/client/API.java | 20 +++++++- .../mastodon/client/Entities/Account.java | 22 +++++++++ .../etalab/mastodon/sqlite/AccountDAO.java | 48 +++++++++++++++++++ .../gouv/etalab/mastodon/sqlite/Sqlite.java | 6 ++- .../main/res/layout/activity_edit_profile.xml | 7 +++ app/src/main/res/values/strings.xml | 1 + 11 files changed, 128 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java index 71cb2e7dc..ffd66b197 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java @@ -93,12 +93,13 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou private ImageView set_profile_picture, set_header_picture; private Button set_change_profile_picture, set_change_header_picture, set_profile_save; private TextView set_header_picture_overlay; - private CheckBox set_lock_account; + private CheckBox set_lock_account, set_sensitive_content; private static final int PICK_IMAGE_HEADER = 4565; private static final int PICK_IMAGE_PROFILE = 6545; private String profile_username, profile_note; private ByteArrayInputStream profile_picture, header_picture; private API.accountPrivacy profile_privacy; + private boolean sensitive; private Bitmap profile_picture_bmp, profile_header_bmp; private ImageView pp_actionBar; private final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE_HEADER = 754; @@ -173,22 +174,26 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou set_profile_save = findViewById(R.id.set_profile_save); set_header_picture_overlay = findViewById(R.id.set_header_picture_overlay); set_lock_account = findViewById(R.id.set_lock_account); - + set_sensitive_content = findViewById(R.id.set_sensitive_content); String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(getApplicationContext())); String instanceVersion = sharedpreferences.getString(Helper.INSTANCE_VERSION + userId + instance, null); Version currentVersion = new Version(instanceVersion); Version minVersion = new Version("2.3"); - if(currentVersion.compareTo(minVersion) == 1) + if(currentVersion.compareTo(minVersion) == 1) { set_lock_account.setVisibility(View.VISIBLE); - else + set_sensitive_content.setVisibility(View.VISIBLE); + }else { set_lock_account.setVisibility(View.GONE); + set_sensitive_content.setVisibility(View.GONE); + } + 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); set_lock_account.setEnabled(false); - + set_sensitive_content.setEnabled(false); new RetrieveAccountInfoAsyncTask(getApplicationContext(), EditProfileActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -231,10 +236,15 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou set_profile_name.setEnabled(true); set_profile_description.setEnabled(true); set_lock_account.setEnabled(true); + set_sensitive_content.setEnabled(true); if( account.isLocked()) set_lock_account.setChecked(true); else set_lock_account.setChecked(false); + if( account.isSensitive()) + set_sensitive_content.setChecked(true); + else + set_sensitive_content.setChecked(false); set_profile_description.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @@ -438,6 +448,7 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou } } profile_privacy = set_lock_account.isChecked()?API.accountPrivacy.LOCKED:API.accountPrivacy.PUBLIC; + sensitive = set_sensitive_content.isChecked(); dialogBuilder.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { @@ -467,7 +478,7 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou newCustomFields.put(key3,val3); newCustomFields.put(key4,val4); - new UpdateCredentialAsyncTask(getApplicationContext(), newCustomFields, profile_username, profile_note, profile_picture, avatarName, header_picture, headerName, profile_privacy, EditProfileActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new UpdateCredentialAsyncTask(getApplicationContext(), newCustomFields, profile_username, profile_note, profile_picture, avatarName, header_picture, headerName, profile_privacy, sensitive, EditProfileActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } }); dialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index ac637a2ca..8eb4b0ade 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -1771,6 +1771,9 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, toot_picture.setEnabled(true); toot_it.setEnabled(true); toot_sensitive.setVisibility(View.VISIBLE); + if( account.isSensitive()){ + toot_sensitive.setChecked(true); + } picture_scrollview.setVisibility(View.VISIBLE); }else { if( attachments.size() > index && attachment.getDescription() != null) { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java index 1e30904af..86c799d86 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java @@ -97,7 +97,7 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask { editor.putString(Helper.PREF_INSTANCE, instance); editor.apply(); if( userExists) - new AccountDAO(this.contextReference.get(), db).updateAccount(account); + new AccountDAO(this.contextReference.get(), db).updateAccountCredential(account); else { if( account.getUsername() != null && account.getCreated_at() != null) new AccountDAO(this.contextReference.get(), db).insertAccount(account); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoByIDAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoByIDAsyncTask.java index 351be5752..f14de0af7 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoByIDAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoByIDAsyncTask.java @@ -60,7 +60,7 @@ public class UpdateAccountInfoByIDAsyncTask extends AsyncTask String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); Account account = null; if( social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) - account = new API(this.contextReference.get()).getAccount(userId); + account = new API(this.contextReference.get()).verifyCredentials(); else if( social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) { account = new PeertubeAPI(this.contextReference.get()).verifyCredentials(); account.setSocial("PEERTUBE"); @@ -78,7 +78,7 @@ public class UpdateAccountInfoByIDAsyncTask extends AsyncTask if( accountDb != null){ account.setInstance(accountDb.getInstance()); account.setToken(accountDb.getToken()); - new AccountDAO(this.contextReference.get(), db).updateAccount(account); + new AccountDAO(this.contextReference.get(), db).updateAccountCredential(account); } } if( social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateCredentialAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateCredentialAsyncTask.java index 672aff268..4b6c1752e 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateCredentialAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateCredentialAsyncTask.java @@ -34,6 +34,7 @@ import fr.gouv.etalab.mastodon.interfaces.OnUpdateCredentialInterface; public class UpdateCredentialAsyncTask extends AsyncTask { private String display_name, note, avatarName, headerName; + private boolean senstive; private ByteArrayInputStream avatar, header; private API.accountPrivacy privacy; private APIResponse apiResponse; @@ -41,7 +42,7 @@ public class UpdateCredentialAsyncTask extends AsyncTask { private WeakReference contextReference; private HashMap customFields; - public UpdateCredentialAsyncTask(Context context, HashMap customFields, String display_name, String note, ByteArrayInputStream avatar, String avatarName, ByteArrayInputStream header, String headerName, API.accountPrivacy privacy, OnUpdateCredentialInterface onUpdateCredentialInterface){ + public UpdateCredentialAsyncTask(Context context, HashMap customFields, String display_name, String note, ByteArrayInputStream avatar, String avatarName, ByteArrayInputStream header, String headerName, API.accountPrivacy privacy, boolean senstive, OnUpdateCredentialInterface onUpdateCredentialInterface){ this.contextReference = new WeakReference<>(context); this.display_name = display_name; this.note = note; @@ -52,11 +53,12 @@ public class UpdateCredentialAsyncTask extends AsyncTask { this.avatarName = avatarName; this.headerName = headerName; this.customFields = customFields; + this.senstive = senstive; } @Override protected Void doInBackground(Void... params) { - apiResponse = new API(this.contextReference.get()).updateCredential(display_name, note, avatar, avatarName, header, headerName, privacy, customFields); + apiResponse = new API(this.contextReference.get()).updateCredential(display_name, note, avatar, avatarName, header, headerName, privacy, customFields, senstive); return null; } 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 3a9289366..e4a2d98aa 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 @@ -314,7 +314,7 @@ public class API { * Update credential of the authenticated user *synchronously* * @return APIResponse */ - public APIResponse updateCredential(String display_name, String note, ByteArrayInputStream avatar, String avatarName, ByteArrayInputStream header, String headerName, accountPrivacy privacy, HashMap customFields) { + public APIResponse updateCredential(String display_name, String note, ByteArrayInputStream avatar, String avatarName, ByteArrayInputStream header, String headerName, accountPrivacy privacy, HashMap customFields, boolean sensitive) { HashMap requestParams = new HashMap<>(); if( display_name != null) @@ -342,6 +342,9 @@ public class API { i++; } } + if(sensitive){ + requestParams.put("source[sensitive]", String.valueOf(sensitive)); + } try { new HttpsConnection(context).patch(getAbsoluteUrl("/accounts/update_credentials"), 60, requestParams, avatar, avatarName, header, headerName, prefKeyOauthTokenT); } catch (HttpsConnection.HttpsConnectionException e) { @@ -393,7 +396,7 @@ public class API { } }if( values.containsKey("refresh_token") && values.get("refresh_token") != null) targetedAccount.setRefresh_token(values.get("refresh_token")); - new AccountDAO(context, db).updateAccount(targetedAccount); + new AccountDAO(context, db).updateAccountCredential(targetedAccount); String response; try { response = new HttpsConnection(context).get(getAbsoluteUrl("/accounts/verify_credentials"), 60, null, targetedAccount.getToken()); @@ -4454,6 +4457,8 @@ public class API { account.setFieldsVerified(fieldsMapVerified); }catch (Exception ignored){} + + //Retrieves emjis List emojiList = new ArrayList<>(); try { @@ -4469,6 +4474,17 @@ public class API { }catch (Exception e){ account.setEmojis(new ArrayList<>()); } + if( resobj.has("source")){ + JSONObject source = resobj.getJSONObject("source"); + try{ + account.setPrivacy(source.getString("privacy")); + account.setSensitive(source.getBoolean("sensitive")); + }catch (Exception e){ + account.setPrivacy("public"); + account.setSensitive(false); + e.printStackTrace(); + } + } } catch (JSONException ignored) {} catch (ParseException e) { e.printStackTrace(); } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Account.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Account.java index a4928dcf0..753f74aa0 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Account.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Account.java @@ -117,6 +117,8 @@ public class Account implements Parcelable { private String refresh_token; private boolean isModerator = false; private boolean isAdmin = false; + private String privacy = "public"; + private boolean sensitive = false; @@ -172,6 +174,8 @@ public class Account implements Parcelable { dest.writeString(this.refresh_token); dest.writeByte(this.isModerator ? (byte) 1 : (byte) 0); dest.writeByte(this.isAdmin ? (byte) 1 : (byte) 0); + dest.writeString(this.privacy); + dest.writeByte(this.sensitive ? (byte) 1 : (byte) 0); } public Account() { @@ -225,6 +229,8 @@ public class Account implements Parcelable { this.refresh_token = in.readString(); this.isModerator = in.readByte() != 0; this.isAdmin = in.readByte() != 0; + this.privacy = in.readString(); + this.sensitive =in.readByte() != 0; } public static final Creator CREATOR = new Creator() { @@ -384,6 +390,22 @@ public class Account implements Parcelable { this.updated_at = updated_at; } + public String getPrivacy() { + return privacy; + } + + public void setPrivacy(String privacy) { + this.privacy = privacy; + } + + public boolean isSensitive() { + return sensitive; + } + + public void setSensitive(boolean sensitive) { + this.sensitive = sensitive; + } + public enum followAction{ FOLLOW, diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/AccountDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/AccountDAO.java index 058fc7caf..4ffd4a7f9 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/AccountDAO.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/AccountDAO.java @@ -82,6 +82,8 @@ public class AccountDAO { if( account.getToken() != null) values.put(Sqlite.COL_OAUTHTOKEN, account.getToken()); + values.put(Sqlite.COL_SENSITIVE, account.isSensitive()); + values.put(Sqlite.COL_PRIVACY, account.getPrivacy()); //Inserts account try{ db.insert(Sqlite.TABLE_USER_ACCOUNT, null, values); @@ -128,7 +130,49 @@ public class AccountDAO { } if( account.getToken() != null) values.put(Sqlite.COL_OAUTHTOKEN, account.getToken()); + return db.update(Sqlite.TABLE_USER_ACCOUNT, + values, Sqlite.COL_USER_ID + " = ? AND " + Sqlite.COL_USERNAME + " =?", + new String[]{account.getId(), account.getUsername()}); + } + + /** + * Update an Account in database + * @param account Account + * @return boolean + */ + public int updateAccountCredential(Account account) + { + ContentValues values = new ContentValues(); + if( account.getNote() == null) + account.setNote(""); + if( account.getCreated_at() == null) + account.setCreated_at(new Date()); + values.put(Sqlite.COL_ACCT, account.getAcct()); + values.put(Sqlite.COL_DISPLAYED_NAME, account.getDisplay_name()); + values.put(Sqlite.COL_LOCKED,account.isLocked()); + values.put(Sqlite.COL_FOLLOWERS_COUNT,account.getFollowers_count()); + values.put(Sqlite.COL_FOLLOWING_COUNT,account.getFollowing_count()); + values.put(Sqlite.COL_STATUSES_COUNT,account.getStatuses_count()); + values.put(Sqlite.COL_NOTE,account.getNote()); + values.put(Sqlite.COL_URL,account.getUrl()); + values.put(Sqlite.COL_AVATAR,account.getAvatar()); + values.put(Sqlite.COL_AVATAR_STATIC,account.getAvatar_static()); + values.put(Sqlite.COL_HEADER,account.getHeader()); + values.put(Sqlite.COL_HEADER_STATIC,account.getHeader_static()); + values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at())); + values.put(Sqlite.COL_INSTANCE, account.getInstance()); + values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis())); + values.put(Sqlite.COL_SOCIAL, account.getSocial()); + if( account.getClient_id() != null && account.getClient_secret() != null && account.getRefresh_token() != null) { + values.put(Sqlite.COL_CLIENT_ID, account.getClient_id()); + values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret()); + values.put(Sqlite.COL_REFRESH_TOKEN, account.getRefresh_token()); + } + if( account.getToken() != null) + values.put(Sqlite.COL_OAUTHTOKEN, account.getToken()); + values.put(Sqlite.COL_SENSITIVE, account.isSensitive()); + values.put(Sqlite.COL_PRIVACY, account.getPrivacy()); return db.update(Sqlite.TABLE_USER_ACCOUNT, values, Sqlite.COL_USER_ID + " = ? AND " + Sqlite.COL_USERNAME + " =?", new String[]{account.getId(), account.getUsername()}); @@ -325,6 +369,8 @@ public class AccountDAO { account.setClient_id(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_ID))); account.setClient_secret(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_SECRET))); account.setRefresh_token(c.getString(c.getColumnIndex(Sqlite.COL_REFRESH_TOKEN))); + account.setSensitive(c.getInt(c.getColumnIndex(Sqlite.COL_SENSITIVE)) == 1); + account.setPrivacy((c.getString(c.getColumnIndex(Sqlite.COL_PRIVACY)))); //Close the cursor c.close(); @@ -368,6 +414,8 @@ public class AccountDAO { account.setClient_id(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_ID))); account.setClient_secret(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_SECRET))); account.setRefresh_token(c.getString(c.getColumnIndex(Sqlite.COL_REFRESH_TOKEN))); + account.setSensitive(c.getInt(c.getColumnIndex(Sqlite.COL_SENSITIVE)) == 1); + account.setPrivacy((c.getString(c.getColumnIndex(Sqlite.COL_PRIVACY)))); accounts.add(account); } //Close the cursor diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java index 1495045ed..9b4132bf6 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java @@ -46,7 +46,7 @@ import fr.gouv.etalab.mastodon.helper.Helper; public class Sqlite extends SQLiteOpenHelper { - public static final int DB_VERSION = 28; + public static final int DB_VERSION = 29; public static final String DB_NAME = "mastodon_etalab_db"; public static SQLiteDatabase db; private static Sqlite sInstance; @@ -115,6 +115,7 @@ public class Sqlite extends SQLiteOpenHelper { static final String COL_IS_MODERATOR = "IS_MODERATOR"; static final String COL_IS_ADMIN = "IS_ADMIN"; static final String COL_UPDATED_AT = "UPDATED_AT"; + static final String COL_PRIVACY = "PRIVACY"; private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " (" + COL_USER_ID + " TEXT PRIMARY KEY, " + COL_USERNAME + " TEXT NOT NULL, " + COL_ACCT + " TEXT NOT NULL, " @@ -389,6 +390,9 @@ public class Sqlite extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_TRACKING_BLOCK); case 27: db.execSQL(CREATE_TABLE_TIMELINES); + case 28: + db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_PRIVACY + " TEXT"); + db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_SENSITIVE + " INTEGER DEFAULT 0"); default: break; } diff --git a/app/src/main/res/layout/activity_edit_profile.xml b/app/src/main/res/layout/activity_edit_profile.xml index 8fa294bac..bbd794e79 100644 --- a/app/src/main/res/layout/activity_edit_profile.xml +++ b/app/src/main/res/layout/activity_edit_profile.xml @@ -207,6 +207,13 @@ android:text="@string/set_lock_account" android:layout_height="wrap_content" /> + +