From f9a14c4a92b036ebf62a81b0e47244eeac571733 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 09:06:22 +0100 Subject: [PATCH 1/8] Begin working on improved leave & delete Signed-off-by: Mario Danic --- .../talk/adapters/items/ConversationItem.java | 2 +- .../talk/controllers/ContactsController.java | 6 +++--- .../controllers/ConversationInfoController.java | 2 +- .../bottomsheet/CallMenuController.java | 2 +- .../bottomsheet/OperationsMenuController.java | 6 +++--- .../nextcloud/talk/jobs/NotificationWorker.java | 4 ++-- .../json/converters/EnumRoomTypeConverter.java | 14 +++++++------- .../talk/models/json/rooms/Conversation.java | 13 +++++++------ .../websocket/RoomPropertiesWebSocketMessage.java | 2 +- 9 files changed, 26 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java index cfebc83e6..2dd2e396a 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java @@ -176,7 +176,7 @@ public class ConversationItem extends AbstractFlexibleItem invitedUsers = new ArrayList<>(); private ArrayList invitedGroups = new ArrayList<>(); @@ -278,7 +278,7 @@ public class OperationsMenuController extends BaseController { invite = invitedGroups.get(0); } - if (conversationType.equals(Conversation.RoomType.ROOM_PUBLIC_CALL) || + if (conversationType.equals(Conversation.ConversationType.ROOM_PUBLIC_CALL) || !currentUser.hasSpreedCapabilityWithName("empty-group-room")) { retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), "3", invite, null); @@ -307,7 +307,7 @@ public class OperationsMenuController extends BaseController { @Override public void onNext(RoomOverall roomOverall) { conversation = roomOverall.getOcs().getData(); - if (conversationType.equals(Conversation.RoomType.ROOM_PUBLIC_CALL) && isGroupCallWorkaroundFinal) { + if (conversationType.equals(Conversation.ConversationType.ROOM_PUBLIC_CALL) && isGroupCallWorkaroundFinal) { performGroupCallWorkaround(credentials); } else { inviteUsersToAConversation(); diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index a64140f2f..a79b776e9 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -140,12 +140,12 @@ public class NotificationWorker extends Worker { Conversation conversation = roomOverall.getOcs().getData(); intent.putExtra(BundleKeys.KEY_ROOM, Parcels.wrap(conversation)); - if (conversation.getType().equals(Conversation.RoomType.ROOM_TYPE_ONE_TO_ONE_CALL) || + if (conversation.getType().equals(Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) || (!TextUtils.isEmpty(conversation.getObjectType()) && "share:password".equals (conversation.getObjectType()))) { context.startActivity(intent); } else { - if (conversation.getType().equals(Conversation.RoomType.ROOM_GROUP_CALL)) { + if (conversation.getType().equals(Conversation.ConversationType.ROOM_GROUP_CALL)) { conversationType = "group"; } else { conversationType = "public"; diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java index 1d429e003..0d4d062d4 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java @@ -23,23 +23,23 @@ package com.nextcloud.talk.models.json.converters; import com.bluelinelabs.logansquare.typeconverters.IntBasedTypeConverter; import com.nextcloud.talk.models.json.rooms.Conversation; -public class EnumRoomTypeConverter extends IntBasedTypeConverter { +public class EnumRoomTypeConverter extends IntBasedTypeConverter { @Override - public Conversation.RoomType getFromInt(int i) { + public Conversation.ConversationType getFromInt(int i) { switch (i) { case 1: - return Conversation.RoomType.ROOM_TYPE_ONE_TO_ONE_CALL; + return Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL; case 2: - return Conversation.RoomType.ROOM_GROUP_CALL; + return Conversation.ConversationType.ROOM_GROUP_CALL; case 3: - return Conversation.RoomType.ROOM_PUBLIC_CALL; + return Conversation.ConversationType.ROOM_PUBLIC_CALL; default: - return Conversation.RoomType.DUMMY; + return Conversation.ConversationType.DUMMY; } } @Override - public int convertToInt(Conversation.RoomType object) { + public int convertToInt(Conversation.ConversationType object) { switch (object) { case DUMMY: return 0; diff --git a/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java b/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java index e2603814a..ae3562289 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java @@ -45,7 +45,7 @@ public class Conversation { @JsonField(name = "displayName") public String displayName; @JsonField(name = "type", typeConverter = EnumRoomTypeConverter.class) - public RoomType type; + public ConversationType type; @JsonField(name = "count") public long count; @JsonField(name = "lastPing") @@ -79,7 +79,7 @@ public class Conversation { NotificationLevel notificationLevel; public boolean isPublic() { - return (RoomType.ROOM_PUBLIC_CALL.equals(type)); + return (ConversationType.ROOM_PUBLIC_CALL.equals(type)); } public boolean isGuest() { @@ -93,11 +93,12 @@ public class Conversation { } public boolean isNameEditable() { - return (canModerate() && !RoomType.ROOM_TYPE_ONE_TO_ONE_CALL.equals(type)); + return (canModerate() && !ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL.equals(type)); } - public boolean isDeletable() { - return (canModerate() && ((participants != null && participants.size() > 2) || numberOfGuests > 0)); + public boolean canLeave() { + return !canModerate() || (getType() != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && getCount() > 1); + } public enum NotificationLevel { @@ -108,7 +109,7 @@ public class Conversation { } @Parcel - public enum RoomType { + public enum ConversationType { DUMMY, ROOM_TYPE_ONE_TO_ONE_CALL, ROOM_GROUP_CALL, diff --git a/app/src/main/java/com/nextcloud/talk/models/json/websocket/RoomPropertiesWebSocketMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/websocket/RoomPropertiesWebSocketMessage.java index 2e3fe77f3..5c0b2489c 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/websocket/RoomPropertiesWebSocketMessage.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/websocket/RoomPropertiesWebSocketMessage.java @@ -35,5 +35,5 @@ public class RoomPropertiesWebSocketMessage { String name; @JsonField(name = "type", typeConverter = EnumRoomTypeConverter.class) - Conversation.RoomType roomType; + Conversation.ConversationType roomType; } From 857aa24e0849fe649f3c3d6e38685b25d680240f Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 09:41:38 +0100 Subject: [PATCH 2/8] Fix #485 Signed-off-by: Mario Danic --- .../ConversationInfoController.java | 13 ++++++++++-- .../bottomsheet/CallMenuController.java | 20 +++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java index d920da1d6..20288611d 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java @@ -97,7 +97,9 @@ public class ConversationInfoController extends BaseController { RecyclerView recyclerView; @BindView(R.id.deleteConversationAction) MaterialStandardPreference deleteConversationAction; - @BindView(R.id.ownOptions) + @BindView(R.id.leaveConversationAction) + MaterialStandardPreference leaveConversationAction; + @BindView(R.id.otherRoomOptions) MaterialPreferenceCategory ownOptionsCategory; @Inject @@ -296,7 +298,14 @@ public class ConversationInfoController extends BaseController { conversation = roomOverall.getOcs().getData(); ownOptionsCategory.setVisibility(View.VISIBLE); - if (!conversation.isDeletable()) { + + if (!conversation.canLeave()) { + leaveConversationAction.setVisibility(View.GONE); + } else { + leaveConversationAction.setVisibility(View.VISIBLE); + } + + if (!conversation.canModerate()) { deleteConversationAction.setVisibility(View.GONE); } else { deleteConversationAction.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java index 91885f267..1e7f9d6a8 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java @@ -128,12 +128,11 @@ public class CallMenuController extends BaseController implements FlexibleAdapte menuItems.add(new MenuItem(getResources().getString(R.string.nc_configure_room), 0, null)); } - UserEntity currentUser; + UserEntity currentUser = userUtils.getCurrentUser(); if (conversation.isFavorite()) { menuItems.add(new MenuItem(getResources().getString(R.string.nc_remove_from_favorites), 97, DisplayUtils.getTintedDrawable(getResources(), R.drawable.ic_star_border_black_24dp, R.color.grey_600))); - } else if ((currentUser = userUtils.getCurrentUser()) != null && - currentUser.hasSpreedCapabilityWithName("favorites")) { + } else if (currentUser.hasSpreedCapabilityWithName("favorites")) { menuItems.add(new MenuItem(getResources().getString(R.string.nc_add_to_favorites) , 98, DisplayUtils.getTintedDrawable(getResources(), R.drawable.ic_star_black_24dp, R.color.grey_600))); } @@ -143,7 +142,7 @@ public class CallMenuController extends BaseController implements FlexibleAdapte .ic_pencil_grey600_24dp))); } - if (conversation.canModerate()) { + if (conversation.canModerate() && !currentUser.hasSpreedCapabilityWithName("locked-one-to-one-rooms")) { if (!conversation.isPublic()) { menuItems.add(new MenuItem(getResources().getString(R.string.nc_make_call_public), 3, getResources().getDrawable(R.drawable .ic_link_grey600_24px))); @@ -158,6 +157,9 @@ public class CallMenuController extends BaseController implements FlexibleAdapte .ic_lock_plus_grey600_24dp))); } } + + menuItems.add(new MenuItem(getResources().getString(R.string.nc_delete_call), 9, getResources().getDrawable(R.drawable + .ic_delete_grey600_24dp))); } if (conversation.isPublic()) { @@ -169,13 +171,11 @@ public class CallMenuController extends BaseController implements FlexibleAdapte } } - if (conversation.canLeave()) { - menuItems.add(new MenuItem(getResources().getString(R.string.nc_delete_call), 9, getResources().getDrawable(R.drawable - .ic_delete_grey600_24dp))); - } - menuItems.add(new MenuItem(getResources().getString(R.string.nc_leave), 1, getResources().getDrawable(R.drawable - .ic_close_grey600_24dp))); + if (conversation.canLeave()) { + menuItems.add(new MenuItem(getResources().getString(R.string.nc_leave), 1, getResources().getDrawable(R.drawable + .ic_close_grey600_24dp))); + } } else if (menuType.equals(MenuType.SHARE)) { prepareIntent(); List appInfoList = ShareUtils.getShareApps(getActivity(), shareIntent, null, From 252a37e0e847fa2d478c0ce1e862ae7f8cb9498e Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 10:15:00 +0100 Subject: [PATCH 3/8] Hide other options in conversation info Signed-off-by: Mario Danic --- .../ConversationInfoController.java | 2 +- .../layout/controller_conversation_info.xml | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java index 20288611d..f3df4f0dd 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java @@ -99,7 +99,7 @@ public class ConversationInfoController extends BaseController { MaterialStandardPreference deleteConversationAction; @BindView(R.id.leaveConversationAction) MaterialStandardPreference leaveConversationAction; - @BindView(R.id.otherRoomOptions) + @BindView(R.id.ownOptions) MaterialPreferenceCategory ownOptionsCategory; @Inject diff --git a/app/src/main/res/layout/controller_conversation_info.xml b/app/src/main/res/layout/controller_conversation_info.xml index 9c9c24ad0..e6d204de7 100644 --- a/app/src/main/res/layout/controller_conversation_info.xml +++ b/app/src/main/res/layout/controller_conversation_info.xml @@ -62,8 +62,8 @@ android:id="@+id/avatar_image" android:layout_width="@dimen/avatar_size_big" android:layout_height="@dimen/avatar_size_big" - apc:roundAsCircle="true" - android:layout_centerHorizontal="true" /> + android:layout_centerHorizontal="true" + apc:roundAsCircle="true" /> - + apc:mp_title="@string/nc_add_to_favorites"> + @@ -119,29 +119,29 @@ tools:listitem="@layout/rv_item_contact"> - + + android:visibility="gone"> + apc:mp_title="@string/nc_leave" /> + apc:mp_icon_tint="@color/grey_600" + apc:mp_title="@string/nc_delete_call" /> From d8e6b9f6efc4bca4b8cb71343434a4125e6ee456 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 11:47:50 +0100 Subject: [PATCH 4/8] Fix #487 Signed-off-by: Mario Danic --- .../talk/controllers/SettingsController.java | 107 ++++++++++++++---- app/src/main/res/values/strings.xml | 2 + 2 files changed, 86 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java index b8ac8b14f..8e9c59c1f 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java @@ -62,6 +62,7 @@ import com.nextcloud.talk.jobs.AccountRemovalWorker; import com.nextcloud.talk.models.RingtoneSettings; import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.utils.ApiUtils; +import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.DoNotDisturbUtils; import com.nextcloud.talk.utils.SecurityUtils; import com.nextcloud.talk.utils.bundle.BundleKeys; @@ -70,6 +71,8 @@ import com.nextcloud.talk.utils.glide.GlideApp; import com.nextcloud.talk.utils.preferences.AppPreferences; import com.nextcloud.talk.utils.preferences.MagicUserInputModule; import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder; +import com.yarolegovich.lovelydialog.LovelySaveStateHandler; +import com.yarolegovich.lovelydialog.LovelyStandardDialog; import com.yarolegovich.mp.*; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; @@ -178,6 +181,8 @@ public class SettingsController extends BaseController { @Inject Context context; + private LovelySaveStateHandler saveStateHandler; + private UserEntity currentUser; private String credentials; @@ -190,6 +195,8 @@ public class SettingsController extends BaseController { private Disposable profileQueryDisposable; private Disposable dbQueryDisposable; + private static final int ID_REMOVE_ACCOUNT_WARNING_DIALOG = 0; + @Override protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) { return inflater.inflate(R.layout.controller_settings, container, false); @@ -210,6 +217,10 @@ public class SettingsController extends BaseController { getCurrentUser(); + if (saveStateHandler == null) { + saveStateHandler = new LovelySaveStateHandler(); + } + appPreferences.registerProxyTypeListener(proxyTypeChangeListener = new ProxyTypeChangeListener()); appPreferences.registerProxyCredentialsListener(proxyCredentialsChangeListener = new ProxyCredentialsChangeListener()); appPreferences.registerScreenSecurityListener(screenSecurityChangeListener = new ScreenSecurityChangeListener()); @@ -302,7 +313,6 @@ public class SettingsController extends BaseController { .popChangeHandler(new VerticalChangeHandler())); }); - String host = null; int port = -1; @@ -338,6 +348,78 @@ public class SettingsController extends BaseController { ())); } + private void showLovelyDialog(int dialogId, Bundle savedInstanceState) { + switch (dialogId) { + case ID_REMOVE_ACCOUNT_WARNING_DIALOG: + showRemoveAccountWarning(savedInstanceState); + break; + default: + break; + } + } + + @Override + protected void onSaveViewState(@NonNull View view, @NonNull Bundle outState) { + saveStateHandler.saveInstanceState(outState); + super.onSaveViewState(view, outState); + } + + @Override + protected void onRestoreViewState(@NonNull View view, @NonNull Bundle savedViewState) { + super.onRestoreViewState(view, savedViewState); + if (LovelySaveStateHandler.wasDialogOnScreen(savedViewState)) { + //Dialog won't be restarted automatically, so we need to call this method. + //Each dialog knows how to restore its state + showLovelyDialog(LovelySaveStateHandler.getSavedDialogId(savedViewState), savedViewState); + } + } + + private void showRemoveAccountWarning(Bundle savedInstanceState) { + if (getActivity() != null) { + new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) + .setTopColorRes(R.color.nc_darkRed) + .setIcon(DisplayUtils.getTintedDrawable(getResources(), + R.drawable.ic_delete_black_24dp, R.color.white)) + .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed)) + .setTitle(R.string.nc_settings_remove_account) + .setMessage(R.string.nc_settings_remove_confirmation) + .setPositiveButton(R.string.nc_settings_remove, new View.OnClickListener() { + @Override + public void onClick(View v) { + removeCurrentAccount(); + } + }) + .setNegativeButton(R.string.nc_cancel, null) + .setInstanceStateHandler(ID_REMOVE_ACCOUNT_WARNING_DIALOG, saveStateHandler) + .setSavedInstanceState(savedInstanceState) + .show(); + } + } + + private void removeCurrentAccount() { + boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId()); + + OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build(); + WorkManager.getInstance().enqueue(accountRemovalWork); + + if (otherUserExists && getView() != null) { + onViewBound(getView()); + onAttach(getView()); + } else if (!otherUserExists) { + if (getParentController() == null || getParentController().getRouter() == null) { + if (getActivity() != null) { + // Something went very wrong, finish the app + getActivity().finish(); + } + } else { + getParentController().getRouter().setRoot(RouterTransaction.with( + new ServerSelectionController()) + .pushChangeHandler(new VerticalChangeHandler()) + .popChangeHandler(new VerticalChangeHandler())); + } + } + } + @Override protected void onAttach(@NonNull View view) { super.onAttach(view); @@ -495,28 +577,7 @@ public class SettingsController extends BaseController { removeAccountButton.addPreferenceClickListener(view1 -> { - boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId()); - - OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build(); - WorkManager.getInstance().enqueue(accountRemovalWork); - - if (otherUserExists && getView() != null) { - onViewBound(getView()); - onAttach(getView()); - } else if (!otherUserExists) { - if (getParentController() == null || getParentController().getRouter() == null) { - if (getActivity() != null) { - // Something went very wrong, finish the app - getActivity().finish(); - } - } else { - getParentController().getRouter().setRoot(RouterTransaction.with( - new ServerSelectionController()) - .pushChangeHandler(new VerticalChangeHandler()) - .popChangeHandler(new VerticalChangeHandler())); - } - } - + showLovelyDialog(ID_REMOVE_ACCOUNT_WARNING_DIALOG, null); }); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 63867a10f..79922453d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -69,6 +69,8 @@ Reauthorize Set up client certificate Change client certificate + Remove + Please confirm your intent to remove the current account. Remove account Add a new account Only current account can be reauthorized From e936bf747906003a688c7ae086e0d998ea4860a3 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 12:12:25 +0100 Subject: [PATCH 5/8] Fix #486 Signed-off-by: Mario Danic --- .../java/com/nextcloud/talk/activities/MainActivity.java | 1 - .../talk/controllers/AccountVerificationController.java | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.java b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.java index 4797a0ed9..2c64f1e12 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.java @@ -167,5 +167,4 @@ public final class MainActivity extends BaseActivity implements ActionBarProvide super.onBackPressed(); } } - } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java b/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java index 76b440d3d..300a56892 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java @@ -193,8 +193,10 @@ public class AccountVerificationController extends BaseController { } if (isAccountImport) { - getRouter().pushController(RouterTransaction.with(new WebViewLoginController(baseUrl, - false, username, ""))); + getRouter().replaceTopController(RouterTransaction.with(new WebViewLoginController(baseUrl, + false, username, "")) + .pushChangeHandler(new HorizontalChangeHandler()) + .popChangeHandler(new HorizontalChangeHandler())); } else { checkEverything(); } From 649df4ef0770df1b81c14a60e3e435e4b138979e Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 12:44:29 +0100 Subject: [PATCH 6/8] Fix delete in conversation info Signed-off-by: Mario Danic --- .../talk/controllers/ChatController.java | 1 - .../ConversationInfoController.java | 77 +++++++++++++++++-- .../talk/models/json/rooms/Conversation.java | 17 +++- app/src/main/res/values/strings.xml | 6 ++ 4 files changed, 93 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.java b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.java index 3c69d5787..20d53d849 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.java @@ -410,7 +410,6 @@ public class ChatController extends BaseController implements MessagesListAdapte private void showConversationInfoScreen() { Bundle bundle = new Bundle(); bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, conversationUser); - bundle.putString(BundleKeys.KEY_BASE_URL, conversationUser.getBaseUrl()); bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken); getRouter().pushController((RouterTransaction.with(new ConversationInfoController(bundle)) .pushChangeHandler(new HorizontalChangeHandler()) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java index f3df4f0dd..e521945e7 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java @@ -21,6 +21,7 @@ package com.nextcloud.talk.controllers; import android.app.Activity; +import android.content.Context; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; @@ -59,6 +60,8 @@ import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.bundle.BundleKeys; import com.nextcloud.talk.utils.preferencestorage.DatabaseStorageModule; import com.vanniktech.emoji.EmojiTextView; +import com.yarolegovich.lovelydialog.LovelySaveStateHandler; +import com.yarolegovich.lovelydialog.LovelyStandardDialog; import com.yarolegovich.mp.MaterialChoicePreference; import com.yarolegovich.mp.MaterialPreferenceCategory; import com.yarolegovich.mp.MaterialPreferenceScreen; @@ -79,6 +82,8 @@ import java.util.List; @AutoInjector(NextcloudTalkApplication.class) public class ConversationInfoController extends BaseController { + private static final int ID_DELETE_CONVERSATION_DIALOG = 0; + @BindView(R.id.notification_settings) MaterialPreferenceScreen materialPreferenceScreen; @BindView(R.id.progressBar) @@ -104,7 +109,9 @@ public class ConversationInfoController extends BaseController { @Inject NcApi ncApi; - private String baseUrl; + @Inject + Context context; + private String conversationToken; private UserEntity conversationUser; private String credentials; @@ -116,13 +123,14 @@ public class ConversationInfoController extends BaseController { private FlexibleAdapter adapter; private List recyclerViewItems = new ArrayList<>(); + private LovelySaveStateHandler saveStateHandler; + public ConversationInfoController(Bundle args) { super(args); setHasOptionsMenu(true); NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this); conversationUser = args.getParcelable(BundleKeys.KEY_USER_ENTITY); conversationToken = args.getString(BundleKeys.KEY_ROOM_TOKEN); - baseUrl = args.getString(BundleKeys.KEY_BASE_URL); credentials = ApiUtils.getCredentials(conversationUser.getUsername(), conversationUser.getToken()); } @@ -145,6 +153,11 @@ public class ConversationInfoController extends BaseController { @Override protected void onViewBound(@NonNull View view) { super.onViewBound(view); + + if (saveStateHandler == null) { + saveStateHandler = new LovelySaveStateHandler(); + } + materialPreferenceScreen.setStorageModule(new DatabaseStorageModule(conversationUser, conversationToken)); if (adapter == null) { fetchRoomInfo(); @@ -159,6 +172,55 @@ public class ConversationInfoController extends BaseController { } } + private void showLovelyDialog(int dialogId, Bundle savedInstanceState) { + switch (dialogId) { + case ID_DELETE_CONVERSATION_DIALOG: + showDeleteConversationDialog(savedInstanceState); + break; + default: + break; + } + } + + + private void showDeleteConversationDialog(Bundle savedInstanceState) { + if (getActivity() != null) { + new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) + .setTopColorRes(R.color.nc_darkRed) + .setIcon(DisplayUtils.getTintedDrawable(context.getResources(), + R.drawable.ic_delete_black_24dp, R.color.white)) + .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed)) + .setTitle(R.string.nc_delete_call) + .setMessage(conversation.getDeleteWarningMessage()) + .setPositiveButton(R.string.nc_delete, new View.OnClickListener() { + @Override + public void onClick(View v) { + deleteConversation(); + } + }) + .setNegativeButton(R.string.nc_cancel, null) + .setInstanceStateHandler(ID_DELETE_CONVERSATION_DIALOG, saveStateHandler) + .setSavedInstanceState(savedInstanceState) + .show(); + } + } + + @Override + protected void onSaveViewState(@NonNull View view, @NonNull Bundle outState) { + saveStateHandler.saveInstanceState(outState); + super.onSaveViewState(view, outState); + } + + @Override + protected void onRestoreViewState(@NonNull View view, @NonNull Bundle savedViewState) { + super.onRestoreViewState(view, savedViewState); + if (LovelySaveStateHandler.wasDialogOnScreen(savedViewState)) { + //Dialog won't be restarted automatically, so we need to call this method. + //Each dialog knows how to restore its state + showLovelyDialog(LovelySaveStateHandler.getSavedDialogId(savedViewState), savedViewState); + } + } + private void setupAdapter() { Activity activity; @@ -254,8 +316,7 @@ public class ConversationInfoController extends BaseController { } } - @OnClick(R.id.deleteConversationAction) - void deleteConversation() { + private void deleteConversation() { Data data; if ((data = getWorkerData()) != null) { OneTimeWorkRequest deleteConversationWorker = @@ -265,6 +326,11 @@ public class ConversationInfoController extends BaseController { } } + @OnClick(R.id.deleteConversationAction) + void deleteConversationClick() { + showDeleteConversationDialog(null); + } + private Data getWorkerData() { if (!TextUtils.isEmpty(conversationToken) && conversationUser != null) { Data.Builder data = new Data.Builder(); @@ -278,9 +344,8 @@ public class ConversationInfoController extends BaseController { private void popTwoLastControllers() { List backstack = getRouter().getBackstack(); - backstack.remove(backstack.size() - 2); + backstack = backstack.subList(0, backstack.size() - 2); getRouter().setBackstack(backstack, new HorizontalChangeHandler()); - getRouter().popCurrentController(); } private void fetchRoomInfo() { diff --git a/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java b/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java index ae3562289..04e2f8ea2 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/rooms/Conversation.java @@ -20,8 +20,11 @@ */ package com.nextcloud.talk.models.json.rooms; +import android.content.res.Resources; import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonObject; +import com.nextcloud.talk.R; +import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.models.json.chat.ChatMessage; import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter; import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter; @@ -97,10 +100,22 @@ public class Conversation { } public boolean canLeave() { - return !canModerate() || (getType() != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && getCount() > 1); + return !canModerate() || (getType() != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && getParticipants().size() > 1); } + public String getDeleteWarningMessage() { + Resources resources = NextcloudTalkApplication.getSharedApplication().getResources(); + if (getType() == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) { + return String.format(resources.getString(R.string.nc_delete_conversation_one2one), + getDisplayName()); + } else if (getParticipants().size() > 1) { + return resources.getString(R.string.nc_delete_conversation_more); + } + + return resources.getString(R.string.nc_delete_conversation_default); + } + public enum NotificationLevel { DEFAULT, ALWAYS, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 79922453d..660a66048 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -145,6 +145,12 @@ Make conversation public Make conversation private Delete conversation + Delete + Please confirm your intent to remove the conversation. + If you delete the conversation, it will also be + deleted for %1$s. + If you delete the conversation, it will also be deleted for all other participants. + New conversation Join via link Join via web From 3f58e260c0f1033aeb5103a62d61d4e7d3e7f336 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 12:55:46 +0100 Subject: [PATCH 7/8] Fix #483 Signed-off-by: Mario Danic --- .../bottomsheet/CallMenuController.java | 65 ++++++++++++++----- .../bottomsheet/OperationsMenuController.java | 15 ----- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java index 1e7f9d6a8..e09922f98 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java @@ -30,6 +30,9 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.work.Data; +import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkManager; import autodagger.AutoInjector; import butterknife.BindView; import com.bluelinelabs.conductor.RouterTransaction; @@ -41,6 +44,8 @@ import com.nextcloud.talk.adapters.items.MenuItem; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.controllers.base.BaseController; import com.nextcloud.talk.events.BottomSheetLockEvent; +import com.nextcloud.talk.jobs.DeleteConversationWorker; +import com.nextcloud.talk.jobs.LeaveConversationWorker; import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.models.json.rooms.Conversation; import com.nextcloud.talk.utils.DisplayUtils; @@ -75,6 +80,8 @@ public class CallMenuController extends BaseController implements FlexibleAdapte private MenuType menuType; private Intent shareIntent; + private UserEntity currentUser; + public CallMenuController(Bundle args) { super(args); this.conversation = Parcels.unwrap(args.getParcelable(BundleKeys.KEY_ROOM)); @@ -128,7 +135,7 @@ public class CallMenuController extends BaseController implements FlexibleAdapte menuItems.add(new MenuItem(getResources().getString(R.string.nc_configure_room), 0, null)); } - UserEntity currentUser = userUtils.getCurrentUser(); + currentUser = userUtils.getCurrentUser(); if (conversation.isFavorite()) { menuItems.add(new MenuItem(getResources().getString(R.string.nc_remove_from_favorites), 97, DisplayUtils.getTintedDrawable(getResources(), R.drawable.ic_star_border_black_24dp, R.color.grey_600))); @@ -209,21 +216,37 @@ public class CallMenuController extends BaseController implements FlexibleAdapte } if (tag > 0) { - bundle.putInt(BundleKeys.KEY_OPERATION_CODE, tag); - if (tag != 2 && tag != 4 && tag != 6 && tag != 7) { - eventBus.post(new BottomSheetLockEvent(false, 0, false, false)); - getRouter().pushController(RouterTransaction.with(new OperationsMenuController(bundle)) - .pushChangeHandler(new HorizontalChangeHandler()) - .popChangeHandler(new HorizontalChangeHandler())); - } else if (tag != 7) { - getRouter().pushController(RouterTransaction.with(new EntryMenuController(bundle)) - .pushChangeHandler(new HorizontalChangeHandler()) - .popChangeHandler(new HorizontalChangeHandler())); + if (tag == 1 || tag == 9) { + Data data; + if ((data = getWorkerData()) != null) { + if (tag == 1) { + OneTimeWorkRequest leaveConversationWorker = + new OneTimeWorkRequest.Builder(LeaveConversationWorker.class).setInputData(data).build(); + WorkManager.getInstance().enqueue(leaveConversationWorker); + } else { + OneTimeWorkRequest deleteConversationWorker = + new OneTimeWorkRequest.Builder(DeleteConversationWorker.class).setInputData(data).build(); + WorkManager.getInstance().enqueue(deleteConversationWorker); + } + eventBus.post(new BottomSheetLockEvent(true, 0, false, true)); + } } else { - bundle.putParcelable(BundleKeys.KEY_MENU_TYPE, Parcels.wrap(MenuType.SHARE)); - getRouter().pushController(RouterTransaction.with(new CallMenuController(bundle)) - .pushChangeHandler(new HorizontalChangeHandler()) - .popChangeHandler(new HorizontalChangeHandler())); + bundle.putInt(BundleKeys.KEY_OPERATION_CODE, tag); + if (tag != 2 && tag != 4 && tag != 6 && tag != 7) { + eventBus.post(new BottomSheetLockEvent(false, 0, false, false)); + getRouter().pushController(RouterTransaction.with(new OperationsMenuController(bundle)) + .pushChangeHandler(new HorizontalChangeHandler()) + .popChangeHandler(new HorizontalChangeHandler())); + } else if (tag != 7) { + getRouter().pushController(RouterTransaction.with(new EntryMenuController(bundle)) + .pushChangeHandler(new HorizontalChangeHandler()) + .popChangeHandler(new HorizontalChangeHandler())); + } else { + bundle.putParcelable(BundleKeys.KEY_MENU_TYPE, Parcels.wrap(MenuType.SHARE)); + getRouter().pushController(RouterTransaction.with(new CallMenuController(bundle)) + .pushChangeHandler(new HorizontalChangeHandler()) + .popChangeHandler(new HorizontalChangeHandler())); + } } } } @@ -257,4 +280,16 @@ public class CallMenuController extends BaseController implements FlexibleAdapte public enum MenuType { REGULAR, SHARE } + + private Data getWorkerData() { + if (!TextUtils.isEmpty(conversation.getToken())) { + Data.Builder data = new Data.Builder(); + data.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.getToken()); + data.putLong(BundleKeys.KEY_INTERNAL_USER_ID, currentUser.getId()); + return data.build(); + } + + return null; + } + } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java index 8cb4b44d9..df95dd1bf 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java @@ -184,13 +184,6 @@ public class OperationsMenuController extends BaseController { } switch (operationCode) { - case 1: - ncApi.removeSelfFromRoom(credentials, ApiUtils.getUrlForRemoveSelfFromRoom(currentUser.getBaseUrl(), conversation.getToken())) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(operationsObserver); - break; case 2: ncApi.renameRoom(credentials, ApiUtils.getRoom(currentUser.getBaseUrl(), conversation.getToken()), conversation.getName()) @@ -232,14 +225,6 @@ public class OperationsMenuController extends BaseController { .retry(1) .subscribe(operationsObserver); break; - case 9: - ncApi.deleteRoom(credentials, ApiUtils.getRoom(currentUser.getBaseUrl(), - conversation.getToken())) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(operationsObserver); - break; case 10: ncApi.getRoom(credentials, ApiUtils.getRoom(baseUrl, conversationToken)) .subscribeOn(Schedulers.newThread()) From 8007a957559c15b43d5453004472cf87ba00d1f7 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Mon, 4 Mar 2019 15:10:18 +0100 Subject: [PATCH 8/8] Implement confirmation dialog for delete in conversations list Signed-off-by: Mario Danic --- .../ConversationsListController.java | 105 +++++++++++++++++- .../bottomsheet/CallMenuController.java | 45 ++++++-- .../interfaces/ConversationMenuInterface.java | 27 +++++ .../talk/utils/power/PowerManagerUtils.java | 2 + 4 files changed, 164 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/interfaces/ConversationMenuInterface.java diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index 68cdeb418..7756f1425 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -30,6 +30,7 @@ import android.os.Bundle; import android.os.Handler; import android.text.InputType; import android.text.TextUtils; +import android.util.Log; import android.view.*; import android.view.inputmethod.EditorInfo; import android.widget.ProgressBar; @@ -41,6 +42,9 @@ import androidx.core.view.MenuItemCompat; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.work.Data; +import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkManager; import autodagger.AutoInjector; import butterknife.BindView; import com.bluelinelabs.conductor.RouterTransaction; @@ -68,6 +72,8 @@ import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController; import com.nextcloud.talk.events.BottomSheetLockEvent; import com.nextcloud.talk.events.EventStatus; import com.nextcloud.talk.events.MoreMenuClickEvent; +import com.nextcloud.talk.interfaces.ConversationMenuInterface; +import com.nextcloud.talk.jobs.DeleteConversationWorker; import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.models.json.participants.Participant; import com.nextcloud.talk.models.json.rooms.Conversation; @@ -79,6 +85,8 @@ import com.nextcloud.talk.utils.bundle.BundleKeys; import com.nextcloud.talk.utils.database.user.UserUtils; import com.nextcloud.talk.utils.glide.GlideApp; import com.nextcloud.talk.utils.preferences.AppPreferences; +import com.yarolegovich.lovelydialog.LovelySaveStateHandler; +import com.yarolegovich.lovelydialog.LovelyStandardDialog; import eu.davidea.fastscroller.FastScroller; import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager; @@ -101,11 +109,12 @@ import java.util.List; @AutoInjector(NextcloudTalkApplication.class) public class ConversationsListController extends BaseController implements SearchView.OnQueryTextListener, FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener, FastScroller - .OnScrollStateChangeListener { + .OnScrollStateChangeListener, ConversationMenuInterface { public static final String TAG = "ConversationsListController"; private static final String KEY_SEARCH_QUERY = "ContactsController.searchQuery"; + public static final int ID_DELETE_CONVERSATION_DIALOG = 0; @Inject UserUtils userUtils; @@ -116,6 +125,9 @@ public class ConversationsListController extends BaseController implements Searc @Inject NcApi ncApi; + @Inject + Context context; + @Inject AppPreferences appPreferences; @@ -159,6 +171,10 @@ public class ConversationsListController extends BaseController implements Searc private String lastClickedConversationToken; private int scrollTo = 0; + private LovelySaveStateHandler saveStateHandler; + + private Bundle conversationMenuBundle = null; + public ConversationsListController() { super(); setHasOptionsMenu(true); @@ -178,6 +194,10 @@ public class ConversationsListController extends BaseController implements Searc getActionBar().show(); } + if (saveStateHandler == null) { + saveStateHandler = new LovelySaveStateHandler(); + } + if (adapter == null) { adapter = new FlexibleAdapter<>(callItems, getActivity(), true); } else { @@ -505,16 +525,24 @@ public class ConversationsListController extends BaseController implements Searc @Override public void onSaveViewState(@NonNull View view, @NonNull Bundle outState) { - super.onSaveViewState(view, outState); + saveStateHandler.saveInstanceState(outState); + if (searchView != null && !TextUtils.isEmpty(searchView.getQuery())) { outState.putString(KEY_SEARCH_QUERY, searchView.getQuery().toString()); } + + super.onSaveViewState(view, outState); } @Override public void onRestoreViewState(@NonNull View view, @NonNull Bundle savedViewState) { super.onRestoreViewState(view, savedViewState); searchQuery = savedViewState.getString(KEY_SEARCH_QUERY, ""); + if (LovelySaveStateHandler.wasDialogOnScreen(savedViewState)) { + //Dialog won't be restarted automatically, so we need to call this method. + //Each dialog knows how to restore its state + showLovelyDialog(LovelySaveStateHandler.getSavedDialogId(savedViewState), savedViewState); + } } @Override @@ -584,7 +612,7 @@ public class ConversationsListController extends BaseController implements Searc if (shouldShowCallMenuController) { getChildRouter((ViewGroup) view).setRoot( - RouterTransaction.with(new CallMenuController(bundle)) + RouterTransaction.with(new CallMenuController(bundle, this)) .popChangeHandler(new VerticalChangeHandler()) .pushChangeHandler(new VerticalChangeHandler())); } else { @@ -677,7 +705,7 @@ public class ConversationsListController extends BaseController implements Searc @Subscribe(sticky = true, threadMode = ThreadMode.BACKGROUND) public void onMessageEvent(EventStatus eventStatus) { - if (currentUser != null && eventStatus.getUserId() == currentUser.getId()){ + if (currentUser != null && eventStatus.getUserId() == currentUser.getId()) { switch (eventStatus.getEventType()) { case CONVERSATION_UPDATE: if (eventStatus.isAllGood() && !isRefreshing) { @@ -689,4 +717,71 @@ public class ConversationsListController extends BaseController implements Searc } } } -} \ No newline at end of file + + private void showDeleteConversationDialog(Bundle savedInstanceState) { + if (getActivity() != null && conversationMenuBundle != null && currentUser != null && conversationMenuBundle.getLong(BundleKeys.KEY_INTERNAL_USER_ID) == currentUser.getId()) { + + Conversation conversation = + Parcels.unwrap(conversationMenuBundle.getParcelable(BundleKeys.KEY_ROOM)); + + if (conversation != null) { + new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) + .setTopColorRes(R.color.nc_darkRed) + .setIcon(DisplayUtils.getTintedDrawable(context.getResources(), + R.drawable.ic_delete_black_24dp, R.color.white)) + .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed)) + .setTitle(R.string.nc_delete_call) + .setMessage(conversation.getDeleteWarningMessage()) + .setPositiveButton(R.string.nc_delete, new View.OnClickListener() { + @Override + public void onClick(View v) { + Data.Builder data = new Data.Builder(); + data.putLong(BundleKeys.KEY_INTERNAL_USER_ID, + conversationMenuBundle.getLong(BundleKeys.KEY_INTERNAL_USER_ID)); + data.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.getToken()); + conversationMenuBundle = null; + deleteConversation(data.build()); + } + }) + .setNegativeButton(R.string.nc_cancel, new View.OnClickListener() { + @Override + public void onClick(View v) { + conversationMenuBundle = null; + } + }) + .setInstanceStateHandler(ID_DELETE_CONVERSATION_DIALOG, saveStateHandler) + .setSavedInstanceState(savedInstanceState) + .show(); + } + } + } + + private void deleteConversation(Data data) { + OneTimeWorkRequest deleteConversationWorker = + new OneTimeWorkRequest.Builder(DeleteConversationWorker.class).setInputData(data).build(); + WorkManager.getInstance().enqueue(deleteConversationWorker); + } + + private void showLovelyDialog(int dialogId, Bundle savedInstanceState) { + switch (dialogId) { + case ID_DELETE_CONVERSATION_DIALOG: + showDeleteConversationDialog(savedInstanceState); + break; + default: + break; + } + } + + @Override + public void openLovelyDialogWithIdAndBundle(int dialogId, Bundle bundle) { + conversationMenuBundle = bundle; + switch (dialogId) { + case ID_DELETE_CONVERSATION_DIALOG: + showLovelyDialog(dialogId, null); + break; + default: + break; + } + + } +} diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java index e09922f98..2fb650978 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java @@ -28,6 +28,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.work.Data; @@ -42,8 +43,10 @@ import com.nextcloud.talk.R; import com.nextcloud.talk.adapters.items.AppItem; import com.nextcloud.talk.adapters.items.MenuItem; import com.nextcloud.talk.application.NextcloudTalkApplication; +import com.nextcloud.talk.controllers.ConversationsListController; import com.nextcloud.talk.controllers.base.BaseController; import com.nextcloud.talk.events.BottomSheetLockEvent; +import com.nextcloud.talk.interfaces.ConversationMenuInterface; import com.nextcloud.talk.jobs.DeleteConversationWorker; import com.nextcloud.talk.jobs.LeaveConversationWorker; import com.nextcloud.talk.models.database.UserEntity; @@ -81,6 +84,7 @@ public class CallMenuController extends BaseController implements FlexibleAdapte private Intent shareIntent; private UserEntity currentUser; + private ConversationMenuInterface conversationMenuInterface; public CallMenuController(Bundle args) { super(args); @@ -90,6 +94,15 @@ public class CallMenuController extends BaseController implements FlexibleAdapte } } + public CallMenuController(Bundle args, @Nullable ConversationMenuInterface conversationMenuInterface) { + super(args); + this.conversation = Parcels.unwrap(args.getParcelable(BundleKeys.KEY_ROOM)); + if (args.containsKey(BundleKeys.KEY_MENU_TYPE)) { + this.menuType = Parcels.unwrap(args.getParcelable(BundleKeys.KEY_MENU_TYPE)); + } + this.conversationMenuInterface = conversationMenuInterface; + } + @Override protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) { return inflater.inflate(R.layout.controller_call_menu, container, false); @@ -217,19 +230,20 @@ public class CallMenuController extends BaseController implements FlexibleAdapte if (tag > 0) { if (tag == 1 || tag == 9) { - Data data; - if ((data = getWorkerData()) != null) { if (tag == 1) { - OneTimeWorkRequest leaveConversationWorker = - new OneTimeWorkRequest.Builder(LeaveConversationWorker.class).setInputData(data).build(); - WorkManager.getInstance().enqueue(leaveConversationWorker); + Data data; + if ((data = getWorkerData()) != null) { + OneTimeWorkRequest leaveConversationWorker = + new OneTimeWorkRequest.Builder(LeaveConversationWorker.class).setInputData(data).build(); + WorkManager.getInstance().enqueue(leaveConversationWorker); + } } else { - OneTimeWorkRequest deleteConversationWorker = - new OneTimeWorkRequest.Builder(DeleteConversationWorker.class).setInputData(data).build(); - WorkManager.getInstance().enqueue(deleteConversationWorker); + Bundle deleteConversationBundle; + if ((deleteConversationBundle = getDeleteConversationBundle()) != null) { + conversationMenuInterface.openLovelyDialogWithIdAndBundle(ConversationsListController.ID_DELETE_CONVERSATION_DIALOG, deleteConversationBundle); + } } eventBus.post(new BottomSheetLockEvent(true, 0, false, true)); - } } else { bundle.putInt(BundleKeys.KEY_OPERATION_CODE, tag); if (tag != 2 && tag != 4 && tag != 6 && tag != 7) { @@ -243,7 +257,7 @@ public class CallMenuController extends BaseController implements FlexibleAdapte .popChangeHandler(new HorizontalChangeHandler())); } else { bundle.putParcelable(BundleKeys.KEY_MENU_TYPE, Parcels.wrap(MenuType.SHARE)); - getRouter().pushController(RouterTransaction.with(new CallMenuController(bundle)) + getRouter().pushController(RouterTransaction.with(new CallMenuController(bundle, null)) .pushChangeHandler(new HorizontalChangeHandler()) .popChangeHandler(new HorizontalChangeHandler())); } @@ -292,4 +306,15 @@ public class CallMenuController extends BaseController implements FlexibleAdapte return null; } + private Bundle getDeleteConversationBundle() { + if (!TextUtils.isEmpty(conversation.getToken())) { + Bundle bundle = new Bundle(); + bundle.putLong(BundleKeys.KEY_INTERNAL_USER_ID, currentUser.getId()); + bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap(conversation)); + return bundle; + } + + return null; + + } } diff --git a/app/src/main/java/com/nextcloud/talk/interfaces/ConversationMenuInterface.java b/app/src/main/java/com/nextcloud/talk/interfaces/ConversationMenuInterface.java new file mode 100644 index 000000000..8ef3b89a3 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/interfaces/ConversationMenuInterface.java @@ -0,0 +1,27 @@ +/* + * Nextcloud Talk application + * + * @author Mario Danic + * Copyright (C) 2017-2018 Mario Danic + * + * 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. + * + * This program 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 this program. If not, see . + */ + +package com.nextcloud.talk.interfaces; + +import android.os.Bundle; + +public interface ConversationMenuInterface { + void openLovelyDialogWithIdAndBundle(int dialogId, Bundle bundle); +} diff --git a/app/src/main/java/com/nextcloud/talk/utils/power/PowerManagerUtils.java b/app/src/main/java/com/nextcloud/talk/utils/power/PowerManagerUtils.java index f2370639a..df2d0e201 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/power/PowerManagerUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/power/PowerManagerUtils.java @@ -160,6 +160,7 @@ public class PowerManagerUtils { } fullLock.release(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { proximityLock.release(); } @@ -180,6 +181,7 @@ public class PowerManagerUtils { if (!wifiLock.isHeld()) { wifiLock.acquire(); } + fullLock.release( );