diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index 350545ae..c91b65f4 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -108,6 +108,7 @@ import app.fedilab.android.client.entities.api.Instance; import app.fedilab.android.client.entities.api.MastodonList; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.BottomMenu; import app.fedilab.android.client.entities.app.Pinned; import app.fedilab.android.client.entities.app.PinnedTimeline; @@ -142,7 +143,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt public static boolean show_boosts, show_replies, show_art_nsfw; public static String regex_home, regex_local, regex_public; Fragment currentFragment; - private Account account; + private BaseAccount account; private AppBarConfiguration mAppBarConfiguration; private ActivityMainBinding binding; private Pinned pinned; @@ -242,7 +243,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt instanceIntent = extras.getString(Helper.PREF_INSTANCE); if (extras.getInt(Helper.INTENT_ACTION) == Helper.NOTIFICATION_INTENT) { try { - Account account = new Account(BaseMainActivity.this).getUniqAccount(userIdIntent, instanceIntent); + BaseAccount account = new Account(BaseMainActivity.this).getUniqAccount(userIdIntent, instanceIntent); SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this); headerMenuOpen = false; Toasty.info(BaseMainActivity.this, getString(R.string.toast_account_changed, "@" + account.mastodon_account.acct + "@" + account.instance), Toasty.LENGTH_LONG).show(); @@ -379,7 +380,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt headerMainBinding.ownerAccounts.setImageResource(R.drawable.ic_baseline_arrow_drop_up_24); new Thread(() -> { try { - List accounts = new Account(BaseMainActivity.this).getAll(); + List accounts = new Account(BaseMainActivity.this).getAll(); Handler mainHandler = new Handler(Looper.getMainLooper()); Runnable myRunnable = () -> { binding.navView.getMenu().clear(); @@ -390,7 +391,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt SubMenu currentSubmenu = null; String lastInstance = ""; if (accounts != null) { - for (final Account account : accounts) { + for (final BaseAccount account : accounts) { if (!currentToken.equalsIgnoreCase(account.token)) { if (!lastInstance.trim().equalsIgnoreCase(account.instance.trim())) { lastInstance = account.instance.toUpperCase(); @@ -682,12 +683,11 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt .observe(BaseMainActivity.this, account1 -> { //Initialize static var getCurrentAccount(BaseMainActivity.this); - //Set the Mastodon account - Helper.setMastodonAccount(account1); new Thread(() -> { try { //Update account in db new Account(BaseMainActivity.this).insertOrUpdate(getCurrentAccount(BaseMainActivity.this)); + getCurrentAccount(BaseMainActivity.this); } catch (DBException e) { e.printStackTrace(); } diff --git a/app/src/main/java/app/fedilab/android/MainApplication.java b/app/src/main/java/app/fedilab/android/MainApplication.java index a2d40e7d..f880a27e 100644 --- a/app/src/main/java/app/fedilab/android/MainApplication.java +++ b/app/src/main/java/app/fedilab/android/MainApplication.java @@ -75,7 +75,7 @@ public class MainApplication extends MultiDexApplication { super.attachBaseContext(base); MultiDex.install(MainApplication.this); SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(MainApplication.this); - boolean send_crash_reports = sharedpreferences.getBoolean(getString(R.string.SET_SEND_CRASH_REPORTS), false); + boolean send_crash_reports = sharedpreferences.getBoolean(getString(R.string.SET_SEND_CRASH_REPORTS), true); if (send_crash_reports) { ACRA.init(this, new CoreConfigurationBuilder() //core configuration: diff --git a/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java b/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java index 59c32c49..0557a8ac 100644 --- a/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java @@ -70,6 +70,7 @@ import app.fedilab.android.client.entities.api.Mention; import app.fedilab.android.client.entities.api.ScheduledStatus; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.StatusDraft; import app.fedilab.android.databinding.ActivityPaginationBinding; import app.fedilab.android.databinding.PopupContactBinding; @@ -122,7 +123,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana } }; private ActivityPaginationBinding binding; - private Account account; + private BaseAccount account; private String instance, token; private Uri photoFileUri; private ScheduledStatus scheduledStatus; diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java index 473f95b7..72570647 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java @@ -104,7 +104,7 @@ public class Status implements Serializable, Cloneable { public transient boolean isFocused = false; public transient boolean setCursorToEnd = false; public transient int cursorPosition = 0; - + public transient boolean submitted = false; @NonNull public Object clone() throws CloneNotSupportedException { return super.clone(); diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/Account.java b/app/src/main/java/app/fedilab/android/client/entities/app/Account.java index 5157e26a..341e6e93 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/Account.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/Account.java @@ -20,7 +20,6 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.google.gson.Gson; -import com.google.gson.annotations.SerializedName; import java.io.Serializable; import java.util.ArrayList; @@ -37,36 +36,10 @@ import app.fedilab.android.sqlite.Sqlite; * Accounts details are serialized and can be for different softwares * The type of the software is stored in api field */ -public class Account implements Serializable { +public class Account extends BaseAccount implements Serializable { private final SQLiteDatabase db; - @SerializedName("user_id") - public String user_id; - @SerializedName("instance") - public String instance; - @SerializedName("api") - public API api; - @SerializedName("software") - public String software; - @SerializedName("token") - public String token; - @SerializedName("refresh_token") - public String refresh_token; - @SerializedName("token_validity") - public long token_validity; - @SerializedName("client_id") - public String client_id; - @SerializedName("client_secret") - public String client_secret; - @SerializedName("created_at") - public Date created_at; - @SerializedName("updated_at") - public Date updated_at; - @SerializedName("mastodon_account") - public app.fedilab.android.client.entities.api.Account mastodon_account; - @SerializedName("admin") - public boolean admin; private transient Context context; @@ -81,9 +54,9 @@ public class Account implements Serializable { } /** - * Serialized a Mastodon Account class + * Serialized a Mastodon BaseAccount class * - * @param mastodon_account {@link app.fedilab.android.client.entities.api.Account} to serialize + * @param mastodon_account {@link BaseAccount} to serialize * @return String serialized account */ public static String mastodonAccountToStringStorage(app.fedilab.android.client.entities.api.Account mastodon_account) { @@ -96,7 +69,7 @@ public class Account implements Serializable { } /** - * Unserialized a Mastodon Account + * Unserialized a Mastodon BaseAccount * * @param serializedAccount String serialized account * @return {@link app.fedilab.android.client.entities.api.Account} @@ -111,11 +84,11 @@ public class Account implements Serializable { } /** - * Returns all Account in db + * Returns all BaseAccount in db * - * @return Account List + * @return BaseAccount List */ - public List getPushNotificationAccounts() { + public List getPushNotificationAccounts() { try { Cursor c = db.query(Sqlite.TABLE_USER_ACCOUNT, null, "(" + Sqlite.COL_API + " = 'MASTODON' OR " + Sqlite.COL_API + " = 'PLEROMA' OR " + Sqlite.COL_API + " = 'FRIENDICA') AND " + Sqlite.COL_TOKEN + " IS NOT NULL", null, null, null, Sqlite.COL_INSTANCE + " ASC", null); @@ -128,11 +101,11 @@ public class Account implements Serializable { /** * Insert or update a user * - * @param account {@link Account} + * @param account {@link BaseAccount} * @return long - db id * @throws DBException exception with database */ - public long insertOrUpdate(Account account) throws DBException { + public long insertOrUpdate(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -149,11 +122,11 @@ public class Account implements Serializable { /** * Insert an account in db * - * @param account {@link Account} + * @param account {@link BaseAccount} * @return long - db id * @throws DBException exception with database */ - private long insertAccount(Account account) throws DBException { + private long insertAccount(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -185,11 +158,11 @@ public class Account implements Serializable { /** * Update an account in db * - * @param account {@link Account} + * @param account {@link BaseAccount} * @return long - db id * @throws DBException exception with database */ - private long updateAccount(Account account) throws DBException { + private long updateAccount(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -223,11 +196,11 @@ public class Account implements Serializable { /** * Check if a user exists in db * - * @param account Account {@link Account} + * @param account BaseAccount {@link BaseAccount} * @return boolean - user exists * @throws DBException Exception */ - public boolean accountExist(Account account) throws DBException { + public boolean accountExist(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -240,13 +213,13 @@ public class Account implements Serializable { } /** - * Returns an Account by userId and instance + * Returns an BaseAccount by userId and instance * * @param userId String * @param instance String - * @return Account {@link Account} + * @return BaseAccount {@link BaseAccount} */ - public Account getUniqAccount(String userId, String instance) throws DBException { + public BaseAccount getUniqAccount(String userId, String instance) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -259,12 +232,12 @@ public class Account implements Serializable { } /** - * Returns an Account by token + * Returns an BaseAccount by token * * @param token String - * @return Account {@link Account} + * @return BaseAccount {@link BaseAccount} */ - public Account getAccountByToken(String token) throws DBException { + public BaseAccount getAccountByToken(String token) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -277,11 +250,11 @@ public class Account implements Serializable { } /** - * Returns authenticated Account + * Returns authenticated BaseAccount * - * @return Account {@link Account} + * @return BaseAccount {@link BaseAccount} */ - public Account getConnectedAccount() throws DBException { + public BaseAccount getConnectedAccount() throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -297,9 +270,9 @@ public class Account implements Serializable { /** * Returns all accounts that allows cross-account actions * - * @return Account List<{@link Account}> + * @return BaseAccount List<{@link BaseAccount}> */ - public List getCrossAccounts() throws DBException { + public List getCrossAccounts() throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -314,9 +287,9 @@ public class Account implements Serializable { /** * Returns all accounts * - * @return Account List<{@link Account}> + * @return BaseAccount List<{@link BaseAccount}> */ - public List getAll() throws DBException { + public List getAll() throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -331,9 +304,9 @@ public class Account implements Serializable { /** * Returns last used account * - * @return Account {@link Account} + * @return BaseAccount {@link BaseAccount} */ - public Account getLastUsedAccount() throws DBException { + public BaseAccount getLastUsedAccount() throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -348,10 +321,10 @@ public class Account implements Serializable { /** * Remove an account from db * - * @param account {@link Account} + * @param account {@link BaseAccount} * @return int */ - public int removeUser(Account account) throws DBException { + public int removeUser(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -360,15 +333,15 @@ public class Account implements Serializable { } - private List cursorToListUser(Cursor c) { + private List cursorToListUser(Cursor c) { //No element found if (c.getCount() == 0) { c.close(); return null; } - List accountList = new ArrayList<>(); + List accountList = new ArrayList<>(); while (c.moveToNext()) { - Account account = convertCursorToAccount(c); + BaseAccount account = convertCursorToAccount(c); //We don't add in the list the current connected account if (!account.token.equalsIgnoreCase(BaseMainActivity.currentToken)) { accountList.add(account); @@ -379,15 +352,15 @@ public class Account implements Serializable { return accountList; } - private List cursorToListUserWithOwner(Cursor c) { + private List cursorToListUserWithOwner(Cursor c) { //No element found if (c.getCount() == 0) { c.close(); return null; } - List accountList = new ArrayList<>(); + List accountList = new ArrayList<>(); while (c.moveToNext()) { - Account account = convertCursorToAccount(c); + BaseAccount account = convertCursorToAccount(c); //We don't add in the list the current connected account accountList.add(account); } @@ -397,11 +370,11 @@ public class Account implements Serializable { } /*** - * Method to hydrate an Account from database + * Method to hydrate an BaseAccount from database * @param c Cursor - * @return Account {@link Account} + * @return BaseAccount {@link BaseAccount} */ - private Account cursorToUser(Cursor c) { + private BaseAccount cursorToUser(Cursor c) { //No element found if (c.getCount() == 0) { c.close(); @@ -410,7 +383,7 @@ public class Account implements Serializable { //Take the first element c.moveToFirst(); //New user - Account account = convertCursorToAccount(c); + BaseAccount account = convertCursorToAccount(c); //Close the cursor c.close(); return account; @@ -420,10 +393,10 @@ public class Account implements Serializable { * Read cursor and hydrate without closing it * * @param c - Cursor - * @return Account + * @return BaseAccount */ - private Account convertCursorToAccount(Cursor c) { - Account account = new Account(); + private BaseAccount convertCursorToAccount(Cursor c) { + BaseAccount account = new BaseAccount(); account.user_id = c.getString(c.getColumnIndexOrThrow(Sqlite.COL_USER_ID)); account.client_id = c.getString(c.getColumnIndexOrThrow(Sqlite.COL_APP_CLIENT_ID)); account.client_secret = c.getString(c.getColumnIndexOrThrow(Sqlite.COL_APP_CLIENT_SECRET)); diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/BaseAccount.java b/app/src/main/java/app/fedilab/android/client/entities/app/BaseAccount.java new file mode 100644 index 00000000..6174bb0c --- /dev/null +++ b/app/src/main/java/app/fedilab/android/client/entities/app/BaseAccount.java @@ -0,0 +1,57 @@ +package app.fedilab.android.client.entities.app; +/* Copyright 2022 Thomas Schneider + * + * This file is a part of Fedilab + * + * 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. + * + * Fedilab 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 Fedilab; if not, + * see . */ + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.Date; + +/** + * Class that manages Accounts from database + * Accounts details are serialized and can be for different softwares + * The type of the software is stored in api field + */ +public class BaseAccount implements Serializable { + + + @SerializedName("user_id") + public String user_id; + @SerializedName("instance") + public String instance; + @SerializedName("api") + public Account.API api; + @SerializedName("software") + public String software; + @SerializedName("token") + public String token; + @SerializedName("refresh_token") + public String refresh_token; + @SerializedName("token_validity") + public long token_validity; + @SerializedName("client_id") + public String client_id; + @SerializedName("client_secret") + public String client_secret; + @SerializedName("created_at") + public Date created_at; + @SerializedName("updated_at") + public Date updated_at; + @SerializedName("mastodon_account") + public app.fedilab.android.client.entities.api.Account mastodon_account; + @SerializedName("admin") + public boolean admin; + +} diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/BottomMenu.java b/app/src/main/java/app/fedilab/android/client/entities/app/BottomMenu.java index f11be421..b617029a 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/BottomMenu.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/BottomMenu.java @@ -118,7 +118,7 @@ public class BottomMenu implements Serializable { return bottomMenu.bottom_menu.get(position).item_menu_type; } - public BottomMenu hydrate(Account account, BottomNavigationView bottomNavigationView) { + public BottomMenu hydrate(BaseAccount account, BottomNavigationView bottomNavigationView) { bottomNavigationView.getMenu().clear(); BottomMenu bottomMenu = null; try { @@ -237,7 +237,7 @@ public class BottomMenu implements Serializable { * @param account Account * @return BottomMenu - {@link BottomMenu} */ - public BottomMenu getAllBottomMenu(Account account) throws DBException { + public BottomMenu getAllBottomMenu(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -256,7 +256,7 @@ public class BottomMenu implements Serializable { * @param account Account * @return BottomMenu - {@link BottomMenu} */ - public BottomMenu getBottomMenu(Account account) throws DBException { + public BottomMenu getBottomMenu(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/Pinned.java b/app/src/main/java/app/fedilab/android/client/entities/app/Pinned.java index 4b8a5673..eb6e87ec 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/Pinned.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/Pinned.java @@ -149,7 +149,7 @@ public class Pinned implements Serializable { * @param account Account * @return Pinned - {@link Pinned} */ - public Pinned getPinned(Account account) throws DBException { + public Pinned getPinned(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -178,7 +178,7 @@ public class Pinned implements Serializable { * @param account Account * @return Pinned - {@link Pinned} */ - public Pinned getAllPinned(Account account) throws DBException { + public Pinned getAllPinned(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/QuickLoad.java b/app/src/main/java/app/fedilab/android/client/entities/app/QuickLoad.java index 424abbeb..39c03685 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/QuickLoad.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/QuickLoad.java @@ -165,6 +165,7 @@ public class QuickLoad { * @return long - db id * @throws DBException exception with database */ + @SuppressWarnings("UnusedReturnValue") public long deleteForAllAccount() throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); @@ -184,7 +185,8 @@ public class QuickLoad { * @return long - db id * @throws DBException exception with database */ - public long deleteForAccount(Account account) throws DBException { + @SuppressWarnings("UnusedReturnValue") + public long deleteForAccount(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -202,11 +204,11 @@ public class QuickLoad { /** * Update a status in quickload * - * @param account {@link Account} + * @param account {@link BaseAccount} * @param newStatus - Status * @throws DBException exception with database */ - public void updateStatus(Account account, Status newStatus) throws DBException { + public void updateStatus(BaseAccount account, Status newStatus) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -279,7 +281,7 @@ public class QuickLoad { * @param id - String id of the status * @throws DBException exception with database */ - public void deleteStatus(Account account, String id) throws DBException { + public void deleteStatus(BaseAccount account, String id) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -375,7 +377,7 @@ public class QuickLoad { * @param ident - the name for pinned timeline * @return SavedValues */ - public QuickLoad getSavedValue(Account account, Timeline.TimeLineEnum timeLineType, String ident) { + public QuickLoad getSavedValue(BaseAccount account, Timeline.TimeLineEnum timeLineType, String ident) { if (cannotBeStored(timeLineType)) { return null; } @@ -455,7 +457,7 @@ public class QuickLoad { * @return Statuses * @throws DBException - throws a db exception */ - private QuickLoad get(String slug, Account account) throws DBException { + private QuickLoad get(String slug, BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/ScheduledBoost.java b/app/src/main/java/app/fedilab/android/client/entities/app/ScheduledBoost.java index b0897375..bc48883a 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/ScheduledBoost.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/ScheduledBoost.java @@ -169,7 +169,7 @@ public class ScheduledBoost implements Serializable { * @param account Account * @return List - List of {@link ScheduledBoost} */ - public List getScheduled(Account account) throws DBException { + public List getScheduled(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/StatusCache.java b/app/src/main/java/app/fedilab/android/client/entities/app/StatusCache.java index 4023bc1d..342a2fef 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/StatusCache.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/StatusCache.java @@ -238,7 +238,7 @@ public class StatusCache { * @return long - db id * @throws DBException exception with database */ - public long deleteForAccount(Account account) throws DBException { + public long deleteForAccount(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/StatusDraft.java b/app/src/main/java/app/fedilab/android/client/entities/app/StatusDraft.java index 41d28368..95e02e50 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/StatusDraft.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/StatusDraft.java @@ -278,7 +278,7 @@ public class StatusDraft implements Serializable { * @param account Account * @return List - List of {@link StatusDraft} */ - public List geStatusDraftList(Account account) throws DBException { + public List geStatusDraftList(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } @@ -297,7 +297,7 @@ public class StatusDraft implements Serializable { * @param account Account * @return List - List of {@link StatusDraft} */ - public List geStatusDraftScheduledList(Account account) throws DBException { + public List geStatusDraftScheduledList(BaseAccount account) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } diff --git a/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java b/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java index df9eb781..74fe0a22 100644 --- a/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java @@ -40,6 +40,7 @@ import app.fedilab.android.client.endpoints.MastodonSearchService; import app.fedilab.android.client.entities.api.Results; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.exception.DBException; import app.fedilab.android.ui.drawer.AccountsSearchAdapter; import app.fedilab.android.viewmodel.mastodon.AccountsVM; @@ -67,14 +68,14 @@ public class CrossActionHelper { final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); new Thread(() -> { try { - List accounts = new Account(context).getCrossAccounts(); + List accounts = new Account(context).getCrossAccounts(); if (accounts.size() == 1) { Handler mainHandler = new Handler(Looper.getMainLooper()); Runnable myRunnable = () -> fetchRemote(context, actionType, accounts.get(0), targetedAccount, targetedStatus); mainHandler.post(myRunnable); } else { List accountList = new ArrayList<>(); - for (Account account : accounts) { + for (BaseAccount account : accounts) { accountList.add(account.mastodon_account); } Handler mainHandler = new Handler(Looper.getMainLooper()); @@ -82,9 +83,9 @@ public class CrossActionHelper { AlertDialog.Builder builderSingle = new AlertDialog.Builder(context, Helper.dialogStyle()); builderSingle.setTitle(context.getString(R.string.choose_accounts)); final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accountList); - final Account[] accountArray = new Account[accounts.size()]; + final BaseAccount[] accountArray = new Account[accounts.size()]; int i = 0; - for (Account account : accounts) { + for (BaseAccount account : accounts) { accountArray[i] = account; i++; } @@ -92,7 +93,7 @@ public class CrossActionHelper { builderSingle.setAdapter(accountsSearchAdapter, (dialog, which) -> { boolean confirmFav = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION_FAV), false); boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true); - Account selectedAccount = accountArray[which]; + BaseAccount selectedAccount = accountArray[which]; if ((actionType == TypeOfCrossAction.REBLOG_ACTION && confirmBoost) || (actionType == TypeOfCrossAction.FAVOURITE_ACTION && confirmFav)) { AlertDialog.Builder alt_bld = new AlertDialog.Builder(context, Helper.dialogStyle()); if (actionType == TypeOfCrossAction.REBLOG_ACTION) { @@ -127,7 +128,7 @@ public class CrossActionHelper { /** * Fetch and federate the remote account or status */ - private static void fetchRemote(@NonNull Context context, @NonNull TypeOfCrossAction actionType, @NonNull Account ownerAccount, app.fedilab.android.client.entities.api.Account targetedAccount, Status targetedStatus) { + private static void fetchRemote(@NonNull Context context, @NonNull TypeOfCrossAction actionType, @NonNull BaseAccount ownerAccount, app.fedilab.android.client.entities.api.Account targetedAccount, Status targetedStatus) { SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get("crossactions", SearchVM.class); if (targetedAccount != null) { @@ -165,7 +166,7 @@ public class CrossActionHelper { /** * Do action when status or account has been fetched */ - private static void applyAction(@NonNull Context context, @NonNull TypeOfCrossAction actionType, @NonNull Account ownerAccount, app.fedilab.android.client.entities.api.Account targetedAccount, Status targetedStatus) { + private static void applyAction(@NonNull Context context, @NonNull TypeOfCrossAction actionType, @NonNull BaseAccount ownerAccount, app.fedilab.android.client.entities.api.Account targetedAccount, Status targetedStatus) { AccountsVM accountsVM = null; StatusesVM statusesVM = null; @@ -263,7 +264,7 @@ public class CrossActionHelper { /** * Fetch and federate the remote status */ - public static void fetchRemoteStatus(@NonNull Context context, @NonNull Account ownerAccount, String url, Callback callback) { + public static void fetchRemoteStatus(@NonNull Context context, @NonNull BaseAccount ownerAccount, String url, Callback callback) { MastodonSearchService mastodonSearchService = init(context, MainActivity.currentInstance); new Thread(() -> { Call resultsCall = mastodonSearchService.search(ownerAccount.token, url, null, "statuses", false, true, false, 0, null, null, 1); @@ -306,7 +307,7 @@ public class CrossActionHelper { /** * Fetch and federate the remote status */ - public static void fetchRemoteAccount(@NonNull Context context, @NonNull Account ownerAccount, app.fedilab.android.client.entities.api.Account targetedAccount, Callback callback) { + public static void fetchRemoteAccount(@NonNull Context context, @NonNull BaseAccount ownerAccount, app.fedilab.android.client.entities.api.Account targetedAccount, Callback callback) { MastodonSearchService mastodonSearchService = init(context, MainActivity.currentInstance); diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index 68971a9c..c15e12c2 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -132,6 +132,7 @@ import app.fedilab.android.activities.WebviewActivity; import app.fedilab.android.broadcastreceiver.ToastMessage; import app.fedilab.android.client.entities.api.Attachment; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.QuickLoad; import app.fedilab.android.client.entities.app.StatusCache; import app.fedilab.android.exception.DBException; @@ -593,68 +594,7 @@ public class Helper { return date; } - /** - * Log out the authenticated user by removing its token - * - * @param activity Activity - * @param account {@link Account} - * @throws DBException Exception - */ - public static void removeAccount(Activity activity, Account account) throws DBException { - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity); - //Current user - String userId = sharedpreferences.getString(PREF_USER_ID, null); - String instance = sharedpreferences.getString(PREF_USER_INSTANCE, null); - Account accountDB = new Account(activity); - boolean accountRemovedIsLogged = false; - //Remove the current account - if (account == null) { - account = accountDB.getUniqAccount(userId, instance); - accountRemovedIsLogged = true; - } - if (account != null) { - Account finalAccount = account; - OauthVM oauthVM = new ViewModelProvider((ViewModelStoreOwner) activity).get(OauthVM.class); - //Revoke the token - oauthVM.revokeToken(account.instance, account.token, account.client_id, account.client_secret); - //Revoke token and remove user - new Thread(() -> { - try { - accountDB.removeUser(finalAccount); - } catch (DBException e) { - e.printStackTrace(); - } - }).start(); - } - //If the account removed is not the logged one, no need to log out the current user - if (!accountRemovedIsLogged) { - return; - } - //Log out the current user - Account newAccount = accountDB.getLastUsedAccount(); - SharedPreferences.Editor editor = sharedpreferences.edit(); - if (newAccount == null) { - editor.putString(PREF_USER_TOKEN, null); - editor.putString(PREF_USER_INSTANCE, null); - editor.putString(PREF_USER_ID, null); - editor.apply(); - Intent loginActivity = new Intent(activity, LoginActivity.class); - activity.startActivity(loginActivity); - activity.finish(); - } else { - editor.putString(PREF_USER_TOKEN, newAccount.token); - editor.putString(PREF_USER_INSTANCE, newAccount.instance); - editor.putString(PREF_USER_ID, newAccount.user_id); - BaseMainActivity.currentUserID = newAccount.user_id; - BaseMainActivity.currentToken = newAccount.token; - BaseMainActivity.currentInstance = newAccount.instance; - editor.apply(); - Intent changeAccount = new Intent(activity, MainActivity.class); - changeAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - activity.startActivity(changeAccount); - } - - } + private static BaseAccount currentAccount; /** * Converts dp to pixel @@ -910,31 +850,66 @@ public class Helper { } /** - * Load a profile picture for the account + * Log out the authenticated user by removing its token * - * @param view ImageView - the view where the image will be loaded - * @param account - {@link Account} + * @param activity Activity + * @param account {@link Account} + * @throws DBException Exception */ - public static void loadPP(ImageView view, Account account) { - Context context = view.getContext(); - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); - boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false); - String targetedUrl = disableGif ? account.mastodon_account.avatar_static : account.mastodon_account.avatar; - if (disableGif || (!targetedUrl.endsWith(".gif"))) { - Glide.with(view.getContext()) - .asDrawable() - .load(targetedUrl) - .thumbnail(0.1f) - .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10))) - .into(view); - } else { - Glide.with(view.getContext()) - .asGif() - .load(targetedUrl) - .thumbnail(0.1f) - .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10))) - .into(view); + public static void removeAccount(Activity activity, BaseAccount account) throws DBException { + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity); + //Current user + String userId = sharedpreferences.getString(PREF_USER_ID, null); + String instance = sharedpreferences.getString(PREF_USER_INSTANCE, null); + Account accountDB = new Account(activity); + boolean accountRemovedIsLogged = false; + //Remove the current account + if (account == null) { + account = accountDB.getUniqAccount(userId, instance); + accountRemovedIsLogged = true; } + if (account != null) { + BaseAccount finalAccount = account; + OauthVM oauthVM = new ViewModelProvider((ViewModelStoreOwner) activity).get(OauthVM.class); + //Revoke the token + oauthVM.revokeToken(account.instance, account.token, account.client_id, account.client_secret); + //Revoke token and remove user + new Thread(() -> { + try { + accountDB.removeUser(finalAccount); + } catch (DBException e) { + e.printStackTrace(); + } + }).start(); + } + //If the account removed is not the logged one, no need to log out the current user + if (!accountRemovedIsLogged) { + return; + } + //Log out the current user + BaseAccount newAccount = accountDB.getLastUsedAccount(); + SharedPreferences.Editor editor = sharedpreferences.edit(); + if (newAccount == null) { + editor.putString(PREF_USER_TOKEN, null); + editor.putString(PREF_USER_INSTANCE, null); + editor.putString(PREF_USER_ID, null); + editor.apply(); + Intent loginActivity = new Intent(activity, LoginActivity.class); + activity.startActivity(loginActivity); + activity.finish(); + } else { + editor.putString(PREF_USER_TOKEN, newAccount.token); + editor.putString(PREF_USER_INSTANCE, newAccount.instance); + editor.putString(PREF_USER_ID, newAccount.user_id); + BaseMainActivity.currentUserID = newAccount.user_id; + BaseMainActivity.currentToken = newAccount.token; + BaseMainActivity.currentInstance = newAccount.instance; + editor.apply(); + Intent changeAccount = new Intent(activity, MainActivity.class); + changeAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + activity.startActivity(changeAccount); + } + } /** @@ -1045,154 +1020,31 @@ public class Helper { } /** - * Sends notification with intent + * Load a profile picture for the account * - * @param context Context - * @param intent Intent associated to the notifcation - * @param icon Bitmap profile picture - * @param title String title of the notification - * @param message String message for the notification + * @param view ImageView - the view where the image will be loaded + * @param account - {@link Account} */ - @SuppressLint("UnspecifiedImmutableFlag") - public static void notify_user(Context context, int notificationId, Account account, Intent intent, Bitmap icon, NotifType notifType, String title, String message) { - final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); - // prepare intent which is triggered if the user click on the notification - NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); - int requestCode = (int) System.currentTimeMillis(); - PendingIntent pIntent; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - pIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT); + public static void loadPP(ImageView view, BaseAccount account) { + Context context = view.getContext(); + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); + boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false); + String targetedUrl = disableGif ? account.mastodon_account.avatar_static : account.mastodon_account.avatar; + if (disableGif || (!targetedUrl.endsWith(".gif"))) { + Glide.with(view.getContext()) + .asDrawable() + .load(targetedUrl) + .thumbnail(0.1f) + .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10))) + .into(view); } else { - pIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_ONE_SHOT); + Glide.with(view.getContext()) + .asGif() + .load(targetedUrl) + .thumbnail(0.1f) + .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10))) + .into(view); } - intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP); - RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); - // build notification - String channelId; - String channelTitle; - - switch (notifType) { - case FAV: - channelId = "channel_favourite"; - channelTitle = context.getString(R.string.channel_notif_fav); - break; - case FOLLLOW: - channelId = "channel_follow"; - channelTitle = context.getString(R.string.channel_notif_follow); - break; - case MENTION: - channelId = "channel_mention"; - channelTitle = context.getString(R.string.channel_notif_mention); - break; - case POLL: - channelId = "channel_poll"; - channelTitle = context.getString(R.string.channel_notif_poll); - break; - case BACKUP: - channelId = "channel_backup"; - channelTitle = context.getString(R.string.channel_notif_backup); - break; - case STORE: - channelId = "channel_store"; - channelTitle = context.getString(R.string.channel_notif_media); - break; - case TOOT: - channelId = "channel_status"; - channelTitle = context.getString(R.string.channel_notif_status); - break; - default: - channelId = "channel_boost"; - channelTitle = context.getString(R.string.channel_notif_boost); - } - NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId) - .setSmallIcon(R.drawable.ic_notification).setTicker(message) - .setWhen(System.currentTimeMillis()) - .setAutoCancel(true); - if (notifType == NotifType.MENTION) { - if (message.length() > 500) { - message = message.substring(0, 499) + "…"; - } - notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(message)); - } - notificationBuilder.setGroup(account.mastodon_account.acct + "@" + account.instance) - .setContentIntent(pIntent) - .setContentText(message); - int ledColour = Color.BLUE; - int prefColor; - try { - prefColor = sharedpreferences.getInt(context.getString(R.string.SET_LED_COLOUR_VAL), LED_COLOUR); - } catch (ClassCastException e) { - prefColor = Integer.parseInt(sharedpreferences.getString(context.getString(R.string.SET_LED_COLOUR_VAL), String.valueOf(LED_COLOUR))); - } - switch (prefColor) { - case 0: // BLUE - ledColour = Color.BLUE; - break; - case 1: // CYAN - ledColour = Color.CYAN; - break; - case 2: // MAGENTA - ledColour = Color.MAGENTA; - break; - case 3: // GREEN - ledColour = Color.GREEN; - break; - case 4: // RED - ledColour = Color.RED; - break; - case 5: // YELLOW - ledColour = Color.YELLOW; - break; - case 6: // WHITE - ledColour = Color.WHITE; - break; - } - - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel channel; - NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - if (sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_SILENT), false)) { - channel = new NotificationChannel(channelId, channelTitle, NotificationManager.IMPORTANCE_LOW); - channel.setSound(null, null); - channel.setVibrationPattern(new long[]{500, 500, 500}); - channel.enableVibration(true); - channel.setLightColor(ledColour); - } else { - channel = new NotificationChannel(channelId, channelTitle, NotificationManager.IMPORTANCE_DEFAULT); - String soundUri = sharedpreferences.getString(context.getString(R.string.SET_NOTIF_SOUND), ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.boop); - AudioAttributes audioAttributes = new AudioAttributes.Builder() - .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - .setUsage(AudioAttributes.USAGE_NOTIFICATION) - .build(); - channel.setSound(Uri.parse(soundUri), audioAttributes); - } - assert mNotificationManager != null; - mNotificationManager.createNotificationChannel(channel); - } else { - if (sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_SILENT), false)) { - notificationBuilder.setVibrate(new long[]{500, 500, 500}); - } else { - String soundUri = sharedpreferences.getString(context.getString(R.string.SET_NOTIF_SOUND), ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.boop); - notificationBuilder.setSound(Uri.parse(soundUri)); - } - notificationBuilder.setLights(ledColour, 500, 1000); - } - notificationBuilder.setContentTitle(title); - notificationBuilder.setLargeIcon(icon); - notificationManager.notify(notificationId, notificationBuilder.build()); - - Notification summaryNotification = - new NotificationCompat.Builder(context, channelId) - .setContentTitle(title) - .setContentText(channelTitle) - .setContentIntent(pIntent) - .setLargeIcon(icon) - .setSmallIcon(R.drawable.ic_notification) - .setGroup(account.mastodon_account.acct + "@" + account.instance) - .setGroupSummary(true) - .build(); - notificationManager.notify(notificationId, summaryNotification); } /** @@ -1547,7 +1399,156 @@ public class Helper { void onAttachmentCopied(Attachment attachment); } - private static WeakReference currentAccount; + /** + * Sends notification with intent + * + * @param context Context + * @param intent Intent associated to the notifcation + * @param icon Bitmap profile picture + * @param title String title of the notification + * @param message String message for the notification + */ + @SuppressLint("UnspecifiedImmutableFlag") + public static void notify_user(Context context, int notificationId, BaseAccount account, Intent intent, Bitmap icon, NotifType notifType, String title, String message) { + final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); + // prepare intent which is triggered if the user click on the notification + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + int requestCode = (int) System.currentTimeMillis(); + PendingIntent pIntent; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + pIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT); + } else { + pIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_ONE_SHOT); + } + intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP); + RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + // build notification + String channelId; + String channelTitle; + + switch (notifType) { + case FAV: + channelId = "channel_favourite"; + channelTitle = context.getString(R.string.channel_notif_fav); + break; + case FOLLLOW: + channelId = "channel_follow"; + channelTitle = context.getString(R.string.channel_notif_follow); + break; + case MENTION: + channelId = "channel_mention"; + channelTitle = context.getString(R.string.channel_notif_mention); + break; + case POLL: + channelId = "channel_poll"; + channelTitle = context.getString(R.string.channel_notif_poll); + break; + case BACKUP: + channelId = "channel_backup"; + channelTitle = context.getString(R.string.channel_notif_backup); + break; + case STORE: + channelId = "channel_store"; + channelTitle = context.getString(R.string.channel_notif_media); + break; + case TOOT: + channelId = "channel_status"; + channelTitle = context.getString(R.string.channel_notif_status); + break; + default: + channelId = "channel_boost"; + channelTitle = context.getString(R.string.channel_notif_boost); + } + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId) + .setSmallIcon(R.drawable.ic_notification).setTicker(message) + .setWhen(System.currentTimeMillis()) + .setAutoCancel(true); + if (notifType == NotifType.MENTION) { + if (message.length() > 500) { + message = message.substring(0, 499) + "…"; + } + notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(message)); + } + notificationBuilder.setGroup(account.mastodon_account.acct + "@" + account.instance) + .setContentIntent(pIntent) + .setContentText(message); + int ledColour = Color.BLUE; + int prefColor; + try { + prefColor = sharedpreferences.getInt(context.getString(R.string.SET_LED_COLOUR_VAL), LED_COLOUR); + } catch (ClassCastException e) { + prefColor = Integer.parseInt(sharedpreferences.getString(context.getString(R.string.SET_LED_COLOUR_VAL), String.valueOf(LED_COLOUR))); + } + switch (prefColor) { + case 0: // BLUE + ledColour = Color.BLUE; + break; + case 1: // CYAN + ledColour = Color.CYAN; + break; + case 2: // MAGENTA + ledColour = Color.MAGENTA; + break; + case 3: // GREEN + ledColour = Color.GREEN; + break; + case 4: // RED + ledColour = Color.RED; + break; + case 5: // YELLOW + ledColour = Color.YELLOW; + break; + case 6: // WHITE + ledColour = Color.WHITE; + break; + } + + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel; + NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_SILENT), false)) { + channel = new NotificationChannel(channelId, channelTitle, NotificationManager.IMPORTANCE_LOW); + channel.setSound(null, null); + channel.setVibrationPattern(new long[]{500, 500, 500}); + channel.enableVibration(true); + channel.setLightColor(ledColour); + } else { + channel = new NotificationChannel(channelId, channelTitle, NotificationManager.IMPORTANCE_DEFAULT); + String soundUri = sharedpreferences.getString(context.getString(R.string.SET_NOTIF_SOUND), ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.boop); + AudioAttributes audioAttributes = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION) + .build(); + channel.setSound(Uri.parse(soundUri), audioAttributes); + } + assert mNotificationManager != null; + mNotificationManager.createNotificationChannel(channel); + } else { + if (sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_SILENT), false)) { + notificationBuilder.setVibrate(new long[]{500, 500, 500}); + } else { + String soundUri = sharedpreferences.getString(context.getString(R.string.SET_NOTIF_SOUND), ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.boop); + notificationBuilder.setSound(Uri.parse(soundUri)); + } + notificationBuilder.setLights(ledColour, 500, 1000); + } + notificationBuilder.setContentTitle(title); + notificationBuilder.setLargeIcon(icon); + notificationManager.notify(notificationId, notificationBuilder.build()); + + Notification summaryNotification = + new NotificationCompat.Builder(context, channelId) + .setContentTitle(title) + .setContentText(channelTitle) + .setContentIntent(pIntent) + .setLargeIcon(icon) + .setSmallIcon(R.drawable.ic_notification) + .setGroup(account.mastodon_account.acct + "@" + account.instance) + .setGroupSummary(true) + .build(); + notificationManager.notify(notificationId, summaryNotification); + } public static void transfertIfExist(Context context) { @@ -1614,23 +1615,15 @@ public class Helper { return "@fedilab_fetch_more_" + uuid; } - public static void setMastodonAccount(app.fedilab.android.client.entities.api.Account mastodon_account) { - if (currentAccount != null) { - currentAccount.get().mastodon_account = mastodon_account; - } - } - - public static Account getCurrentAccount(Context context) { - if (currentAccount == null || currentAccount.get() == null || currentAccount.get().mastodon_account == null) { + public static BaseAccount getCurrentAccount(Context context) { + if (currentAccount == null) { try { - Account account = new Account(context).getUniqAccount(MainActivity.currentUserID, MainActivity.currentInstance); - currentAccount = new WeakReference<>(account); - currentAccount.get().mastodon_account = account.mastodon_account; + currentAccount = new Account(context).getUniqAccount(MainActivity.currentUserID, MainActivity.currentInstance); } catch (DBException e) { e.printStackTrace(); } } - return currentAccount.get(); + return currentAccount; } public static class CacheTask { diff --git a/app/src/main/java/app/fedilab/android/helper/NotificationsHelper.java b/app/src/main/java/app/fedilab/android/helper/NotificationsHelper.java index 4e8fcc38..34c2f9cd 100644 --- a/app/src/main/java/app/fedilab/android/helper/NotificationsHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/NotificationsHelper.java @@ -53,6 +53,7 @@ import app.fedilab.android.client.endpoints.MastodonNotificationsService; import app.fedilab.android.client.entities.api.Notification; import app.fedilab.android.client.entities.api.Notifications; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.exception.DBException; import okhttp3.OkHttpClient; import retrofit2.Call; @@ -70,7 +71,7 @@ public class NotificationsHelper { SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(context); String[] slugArray = slug.split("@"); - Account accountDb = new Account(context).getUniqAccount(slugArray[0], slugArray[1]); + BaseAccount accountDb = new Account(context).getUniqAccount(slugArray[0], slugArray[1]); if (accountDb == null) { return; } @@ -147,7 +148,7 @@ public class NotificationsHelper { return retrofit.create(MastodonNotificationsService.class); } - public static void onRetrieveNotifications(Context context, Notifications newNotifications, final Account account) { + public static void onRetrieveNotifications(Context context, Notifications newNotifications, final BaseAccount account) { List notificationsReceived = newNotifications.notifications; if (notificationsReceived == null || notificationsReceived.size() == 0 || account == null) return; diff --git a/app/src/main/java/app/fedilab/android/helper/PushHelper.java b/app/src/main/java/app/fedilab/android/helper/PushHelper.java index 4a2cce81..b5317fa3 100644 --- a/app/src/main/java/app/fedilab/android/helper/PushHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/PushHelper.java @@ -38,6 +38,7 @@ import java.util.concurrent.TimeUnit; import app.fedilab.android.R; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.jobs.NotificationsWorker; public class PushHelper { @@ -49,7 +50,7 @@ public class PushHelper { switch (typeOfNotification) { case "PUSH_NOTIFICATIONS": new Thread(() -> { - List accounts = new Account(context).getPushNotificationAccounts(); + List accounts = new Account(context).getPushNotificationAccounts(); Handler mainHandler = new Handler(Looper.getMainLooper()); Runnable myRunnable = () -> { List distributors = UnifiedPush.getDistributors(context, new ArrayList<>()); @@ -84,8 +85,8 @@ public class PushHelper { break; case "REPEAT_NOTIFICATIONS": new Thread(() -> { - List accounts = new Account(context).getPushNotificationAccounts(); - for (Account account : accounts) { + List accounts = new Account(context).getPushNotificationAccounts(); + for (BaseAccount account : accounts) { ((Activity) context).runOnUiThread(() -> { UnifiedPush.unregisterApp(context, account.user_id + "@" + account.instance); }); @@ -98,8 +99,8 @@ public class PushHelper { case "NO_NOTIFICATIONS": WorkManager.getInstance(context).cancelAllWorkByTag(Helper.WORKER_REFRESH_NOTIFICATION); new Thread(() -> { - List accounts = new Account(context).getPushNotificationAccounts(); - for (Account account : accounts) { + List accounts = new Account(context).getPushNotificationAccounts(); + for (BaseAccount account : accounts) { ((Activity) context).runOnUiThread(() -> { UnifiedPush.unregisterApp(context, account.user_id + "@" + account.instance); }); @@ -110,7 +111,7 @@ public class PushHelper { } - private static void registerAppWithDialog(Context context, List accounts) { + private static void registerAppWithDialog(Context context, List accounts) { if (accounts == null) { return; } @@ -119,7 +120,7 @@ public class PushHelper { if (distributors.size() == 1) { UnifiedPush.saveDistributor(context, distributors.get(0)); } - for (Account account : accounts) { + for (BaseAccount account : accounts) { UnifiedPush.registerApp(context, account.user_id + "@" + account.instance, new ArrayList<>(), ""); } return; @@ -131,7 +132,7 @@ public class PushHelper { alert.setSingleChoiceItems(distributorsStr, -1, (dialog, item) -> { String distributor = distributorsStr[item]; UnifiedPush.saveDistributor(context, distributor); - for (Account account : accounts) { + for (BaseAccount account : accounts) { UnifiedPush.registerApp(context, account.user_id + "@" + account.instance, new ArrayList<>(), ""); } dialog.dismiss(); diff --git a/app/src/main/java/app/fedilab/android/helper/PushNotifications.java b/app/src/main/java/app/fedilab/android/helper/PushNotifications.java index a45f779d..7182285c 100644 --- a/app/src/main/java/app/fedilab/android/helper/PushNotifications.java +++ b/app/src/main/java/app/fedilab/android/helper/PushNotifications.java @@ -35,6 +35,7 @@ import app.fedilab.android.R; import app.fedilab.android.client.endpoints.MastodonNotificationsService; import app.fedilab.android.client.entities.api.PushSubscription; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.exception.DBException; import okhttp3.OkHttpClient; import retrofit2.Call; @@ -79,7 +80,7 @@ public class PushNotifications { ECDH finalEcdh = ecdh; new Thread(() -> { String[] slugArray = slug.split("@"); - Account accountDb = null; + BaseAccount accountDb = null; try { accountDb = new Account(context).getUniqAccount(slugArray[0], slugArray[1]); } catch (DBException e) { diff --git a/app/src/main/java/app/fedilab/android/services/PostMessageService.java b/app/src/main/java/app/fedilab/android/services/PostMessageService.java index 17cafba8..aac8be34 100644 --- a/app/src/main/java/app/fedilab/android/services/PostMessageService.java +++ b/app/src/main/java/app/fedilab/android/services/PostMessageService.java @@ -45,6 +45,7 @@ import app.fedilab.android.client.entities.api.Poll; import app.fedilab.android.client.entities.api.ScheduledStatus; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.PostState; import app.fedilab.android.client.entities.app.StatusDraft; import app.fedilab.android.exception.DBException; @@ -141,7 +142,7 @@ public class PostMessageService extends IntentService { } if (watermarkText == null) { try { - Account account = new Account(context).getAccountByToken(dataPost.token); + BaseAccount account = new Account(context).getAccountByToken(dataPost.token); watermarkText = account.mastodon_account.username + "@" + account.instance; } catch (DBException e) { e.printStackTrace(); diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java index 3e18dab8..9248e438 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java @@ -91,7 +91,7 @@ import app.fedilab.android.client.entities.api.Mention; import app.fedilab.android.client.entities.api.Poll; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.api.Tag; -import app.fedilab.android.client.entities.app.Account; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.StatusDraft; import app.fedilab.android.databinding.ComposeAttachmentItemBinding; import app.fedilab.android.databinding.ComposePollBinding; @@ -122,7 +122,7 @@ public class ComposeAdapter extends RecyclerView.Adapter statusList; private final int TYPE_NORMAL = 0; - private final Account account; + private final BaseAccount account; private final String visibility; private final app.fedilab.android.client.entities.api.Account mentionedAccount; public ManageDrafts manageDrafts; @@ -130,7 +130,7 @@ public class ComposeAdapter extends RecyclerView.Adapter statusList, int statusCount, Account account, app.fedilab.android.client.entities.api.Account mentionedAccount, String visibility) { + public ComposeAdapter(List statusList, int statusCount, BaseAccount account, app.fedilab.android.client.entities.api.Account mentionedAccount, String visibility) { this.statusList = statusList; this.statusCount = statusCount; this.account = account; @@ -1210,8 +1210,13 @@ public class ComposeAdapter extends RecyclerView.Adapter manageDrafts.onSubmit(prepareDraft(statusList, this, account.instance, account.user_id))); + holder.binding.buttonPost.setOnClickListener(v -> { + statusDraft.submitted = true; + notifyItemChanged(position); + manageDrafts.onSubmit(prepareDraft(statusList, this, account.instance, account.user_id)); + }); } } diff --git a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java index a773fc0e..d31da33b 100644 --- a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java +++ b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java @@ -44,6 +44,7 @@ import app.fedilab.android.client.entities.api.Poll; import app.fedilab.android.client.entities.api.ScheduledStatus; import app.fedilab.android.client.entities.api.ScheduledStatuses; import app.fedilab.android.client.entities.api.Status; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.QuickLoad; import app.fedilab.android.client.entities.app.StatusCache; import app.fedilab.android.exception.DBException; @@ -322,7 +323,7 @@ public class StatusesVM extends AndroidViewModel { } //The status must also be deleted in cache try { - app.fedilab.android.client.entities.app.Account account = new app.fedilab.android.client.entities.app.Account(getApplication().getApplicationContext()).getAccountByToken(token); + BaseAccount account = new app.fedilab.android.client.entities.app.Account(getApplication().getApplicationContext()).getAccountByToken(token); new StatusCache(getApplication().getApplicationContext()).deleteStatus(id, account.instance); new QuickLoad(getApplication().getApplicationContext()).deleteStatus(account, id); } catch (DBException e) { diff --git a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/TimelinesVM.java b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/TimelinesVM.java index 6f63ea14..8e7c3fa1 100644 --- a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/TimelinesVM.java +++ b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/TimelinesVM.java @@ -40,6 +40,7 @@ import app.fedilab.android.client.entities.api.MastodonList; import app.fedilab.android.client.entities.api.Pagination; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.api.Statuses; +import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.StatusCache; import app.fedilab.android.client.entities.app.StatusDraft; import app.fedilab.android.exception.DBException; @@ -286,7 +287,7 @@ public class TimelinesVM extends AndroidViewModel { * @param account app.fedilab.android.client.entities.app.Account * @return LiveData> */ - public LiveData> getDrafts(app.fedilab.android.client.entities.app.Account account) { + public LiveData> getDrafts(BaseAccount account) { statusDraftListMutableLiveData = new MutableLiveData<>(); new Thread(() -> { List statusCacheDAO = null; diff --git a/app/src/main/res/xml/pref_interface.xml b/app/src/main/res/xml/pref_interface.xml index c13dd5d6..b1a0b8ae 100644 --- a/app/src/main/res/xml/pref_interface.xml +++ b/app/src/main/res/xml/pref_interface.xml @@ -27,7 +27,7 @@ app:title="@string/embedded_browser" />