Browse Source

Implement leave & delete in conversation info

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 6 years ago
parent
commit
183c7afd5d
20 changed files with 434 additions and 22 deletions
  1. 1 1
      app/build.gradle
  2. 1 1
      app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java
  3. 2 2
      app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java
  4. 2 2
      app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java
  5. 1 1
      app/src/main/java/com/nextcloud/talk/controllers/ChatController.java
  6. 65 0
      app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java
  7. 22 1
      app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java
  8. 4 4
      app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java
  9. 3 3
      app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java
  10. 1 1
      app/src/main/java/com/nextcloud/talk/events/EventStatus.java
  11. 115 0
      app/src/main/java/com/nextcloud/talk/jobs/DeleteConversationWorker.java
  12. 115 0
      app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java
  13. 2 2
      app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java
  14. 2 0
      app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java
  15. 1 1
      app/src/main/res/drawable/ic_delete_black_24dp.xml
  16. 1 1
      app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml
  17. 25 0
      app/src/main/res/drawable/ic_star_black_24dp.xml
  18. 25 0
      app/src/main/res/drawable/ic_star_border_black_24dp.xml
  19. 1 1
      app/src/main/res/drawable/shape_favorite_bubble.xml
  20. 45 1
      app/src/main/res/layout/controller_conversation_info.xml

+ 1 - 1
app/build.gradle

@@ -17,7 +17,7 @@ android {
         targetSdkVersion 28
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 
-        versionCode 85
+        versionCode 155
         versionName "3.2.6"
 
         flavorDimensions "default"

+ 1 - 1
app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java

@@ -114,7 +114,7 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
 
         holder.serverUrl.setText(userEntity.getBaseUrl());
 
-        if (userEntity.getBaseUrl().startsWith("http://") || userEntity.getBaseUrl().startsWith("https://")) {
+        if (userEntity != null && userEntity.getBaseUrl().startsWith("http://") || userEntity.getBaseUrl().startsWith("https://")) {
             holder.avatarImageView.setVisibility(View.VISIBLE);
             GlideUrl glideUrl = new GlideUrl(ApiUtils.getUrlForAvatarWithName(userEntity.getBaseUrl(),
                     participant.getUserId(), R.dimen.avatar_size), new LazyHeaders.Builder()

+ 2 - 2
app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java

@@ -41,7 +41,7 @@ import com.nextcloud.talk.dagger.modules.RestModule;
 import com.nextcloud.talk.jobs.AccountRemovalWorker;
 import com.nextcloud.talk.jobs.CapabilitiesWorker;
 import com.nextcloud.talk.jobs.PushRegistrationWorker;
-import com.nextcloud.talk.jobs.SignalingSettingsJob;
+import com.nextcloud.talk.jobs.SignalingSettingsWorker;
 import com.nextcloud.talk.utils.ClosedInterfaceImpl;
 import com.nextcloud.talk.utils.DeviceUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
@@ -142,7 +142,7 @@ public class NextcloudTalkApplication extends MultiDexApplication implements Lif
         PeriodicWorkRequest periodicCapabilitiesUpdateWork = new PeriodicWorkRequest.Builder(CapabilitiesWorker.class,
                 1, TimeUnit.DAYS).build();
         OneTimeWorkRequest capabilitiesUpdateWork = new OneTimeWorkRequest.Builder(CapabilitiesWorker.class).build();
-        OneTimeWorkRequest signalingSettingsWork = new OneTimeWorkRequest.Builder(SignalingSettingsJob.class).build();
+        OneTimeWorkRequest signalingSettingsWork = new OneTimeWorkRequest.Builder(SignalingSettingsWorker.class).build();
 
         //WorkManager.initialize(getApplicationContext(), new Configuration.Builder().build());
         WorkManager.getInstance().enqueue(pushRegistrationWork);

+ 2 - 2
app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java

@@ -43,7 +43,7 @@ import com.nextcloud.talk.controllers.base.BaseController;
 import com.nextcloud.talk.events.EventStatus;
 import com.nextcloud.talk.jobs.CapabilitiesWorker;
 import com.nextcloud.talk.jobs.PushRegistrationWorker;
-import com.nextcloud.talk.jobs.SignalingSettingsJob;
+import com.nextcloud.talk.jobs.SignalingSettingsWorker;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.generic.Status;
 import com.nextcloud.talk.models.json.rooms.RoomsOverall;
@@ -395,7 +395,7 @@ public class AccountVerificationController extends BaseController {
                 .putLong(BundleKeys.KEY_INTERNAL_USER_ID, internalAccountId)
                 .build();
 
-        OneTimeWorkRequest signalingSettings = new OneTimeWorkRequest.Builder(SignalingSettingsJob.class)
+        OneTimeWorkRequest signalingSettings = new OneTimeWorkRequest.Builder(SignalingSettingsWorker.class)
                 .setInputData(userData)
                 .build();
         WorkManager.getInstance().enqueue(signalingSettings);

+ 1 - 1
app/src/main/java/com/nextcloud/talk/controllers/ChatController.java

@@ -389,7 +389,7 @@ public class ChatController extends BaseController implements MessagesListAdapte
         messageInputView.getButton().setContentDescription(getResources()
                 .getString(R.string.nc_description_send_message_button));
 
-        if (!conversationUser.getUserId().equals("?") && conversationUser.hasSpreedCapabilityWithName("mention" + "-flag") && getActivity() != null) {
+        if (!conversationUser.getUserId().equals("?") && conversationUser.hasSpreedCapabilityWithName("mention-flag") && getActivity() != null) {
             getActivity().findViewById(R.id.toolbar).setOnClickListener(v -> showConversationInfoScreen());
         }
 

+ 65 - 0
app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java

@@ -23,6 +23,7 @@ package com.nextcloud.talk.controllers;
 import android.app.Activity;
 import android.os.Bundle;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
@@ -30,8 +31,15 @@ import android.view.ViewGroup;
 import android.widget.ProgressBar;
 import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.room.Delete;
+import androidx.work.Data;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkManager;
 import autodagger.AutoInjector;
 import butterknife.BindView;
+import butterknife.OnClick;
+import com.bluelinelabs.conductor.RouterTransaction;
+import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.facebook.drawee.view.SimpleDraweeView;
@@ -40,6 +48,9 @@ import com.nextcloud.talk.adapters.items.UserItem;
 import com.nextcloud.talk.api.NcApi;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.controllers.base.BaseController;
+import com.nextcloud.talk.jobs.DeleteConversationWorker;
+import com.nextcloud.talk.jobs.LeaveConversationWorker;
+import com.nextcloud.talk.jobs.PushRegistrationWorker;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter;
 import com.nextcloud.talk.models.json.participants.Participant;
@@ -54,6 +65,7 @@ import com.vanniktech.emoji.EmojiTextView;
 import com.yarolegovich.mp.MaterialChoicePreference;
 import com.yarolegovich.mp.MaterialPreferenceCategory;
 import com.yarolegovich.mp.MaterialPreferenceScreen;
+import com.yarolegovich.mp.MaterialStandardPreference;
 import eu.davidea.flexibleadapter.FlexibleAdapter;
 import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager;
 import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
@@ -87,6 +99,11 @@ public class ConversationInfoController extends BaseController {
     MaterialPreferenceCategory participantsListCategory;
     @BindView(R.id.recycler_view)
     RecyclerView recyclerView;
+    @BindView(R.id.deleteConversationAction)
+    MaterialStandardPreference deleteConversationAction;
+    @BindView(R.id.ownOptions)
+    MaterialPreferenceCategory ownOptionsCategory;
+
     @Inject
     NcApi ncApi;
     private String baseUrl;
@@ -228,6 +245,46 @@ public class ConversationInfoController extends BaseController {
 
     }
 
+    @OnClick(R.id.leaveConversationAction)
+    void leaveConversation() {
+        Data data;
+        if ((data = getWorkerData()) != null) {
+            OneTimeWorkRequest leaveConversationWorker =
+                    new OneTimeWorkRequest.Builder(LeaveConversationWorker.class).setInputData(data).build();
+            WorkManager.getInstance().enqueue(leaveConversationWorker);
+            popTwoLastControllers();
+        }
+    }
+
+    @OnClick(R.id.deleteConversationAction)
+    void deleteConversation() {
+        Data data;
+        if ((data = getWorkerData()) != null) {
+            OneTimeWorkRequest deleteConversationWorker =
+                    new OneTimeWorkRequest.Builder(DeleteConversationWorker.class).setInputData(data).build();
+            WorkManager.getInstance().enqueue(deleteConversationWorker);
+            popTwoLastControllers();
+        }
+    }
+
+    private Data getWorkerData() {
+        if (!TextUtils.isEmpty(conversationToken) && conversationUser != null) {
+            Data.Builder data = new Data.Builder();
+            data.putString(BundleKeys.KEY_ROOM_TOKEN, conversationToken);
+            data.putLong(BundleKeys.KEY_INTERNAL_USER_ID, conversationUser.getId());
+            return data.build();
+        }
+
+        return null;
+    }
+
+    private void popTwoLastControllers() {
+        List<RouterTransaction> backstack = getRouter().getBackstack();
+        backstack.remove(backstack.size() - 2);
+        getRouter().setBackstack(backstack, new HorizontalChangeHandler());
+        getRouter().popCurrentController();
+    }
+
     private void fetchRoomInfo() {
         ncApi.getRoom(credentials, ApiUtils.getRoom(conversationUser.getBaseUrl(), conversationToken))
                 .subscribeOn(Schedulers.newThread())
@@ -241,6 +298,14 @@ public class ConversationInfoController extends BaseController {
                     @Override
                     public void onNext(RoomOverall roomOverall) {
                         conversation = roomOverall.getOcs().getData();
+
+                        ownOptionsCategory.setVisibility(View.VISIBLE);
+                        if (!conversation.isDeletable()) {
+                            deleteConversationAction.setVisibility(View.GONE);
+                        } else {
+                            deleteConversationAction.setVisibility(View.VISIBLE);
+                        }
+
                         getListOfParticipants();
 
                         if (progressBar != null) {

+ 22 - 1
app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java

@@ -66,6 +66,7 @@ import com.nextcloud.talk.controllers.base.BaseController;
 import com.nextcloud.talk.controllers.bottomsheet.CallMenuController;
 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.models.database.UserEntity;
 import com.nextcloud.talk.models.json.participants.Participant;
@@ -153,6 +154,8 @@ public class ConversationsListController extends BaseController implements Searc
 
     private boolean adapterWasNull = true;
 
+    private boolean isRefreshing;
+
     private String lastClickedConversationToken;
     private int scrollTo = 0;
 
@@ -292,6 +295,8 @@ public class ConversationsListController extends BaseController implements Searc
     private void fetchData(boolean fromBottomSheet) {
         dispose(null);
 
+        isRefreshing = true;
+
         callItems = new ArrayList<>();
 
         roomsQueryDisposable = ncApi.getRooms(credentials, ApiUtils.getUrlForGetRooms(currentUser.getBaseUrl()))
@@ -412,6 +417,7 @@ public class ConversationsListController extends BaseController implements Searc
                         }, 2500);
                     }
 
+                    isRefreshing = false;
                 });
 
     }
@@ -668,4 +674,19 @@ 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()){
+            switch (eventStatus.getEventType()) {
+                case CONVERSATION_UPDATE:
+                    if (eventStatus.isAllGood() && !isRefreshing) {
+                        fetchData(false);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}

+ 4 - 4
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java

@@ -43,6 +43,7 @@ import com.nextcloud.talk.controllers.base.BaseController;
 import com.nextcloud.talk.events.BottomSheetLockEvent;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.rooms.Conversation;
+import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.ShareUtils;
 import com.nextcloud.talk.utils.bundle.BundleKeys;
 import com.nextcloud.talk.utils.database.user.UserUtils;
@@ -130,12 +131,11 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
             UserEntity currentUser;
 
             if (conversation.isFavorite()) {
-                menuItems.add(new MenuItem(getResources().getString(R.string.nc_remove_from_favorites), 97, getResources()
-                        .getDrawable(R.drawable.ic_star_border_grey600_24dp)));
+                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")) {
-                menuItems.add(new MenuItem(getResources().getString(R.string.nc_add_to_favorites), 98, getResources()
-                        .getDrawable(R.drawable.ic_star_grey600_24dp)));
+                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)));
             }
 
             if (conversation.isNameEditable()) {

+ 3 - 3
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java

@@ -185,8 +185,7 @@ public class OperationsMenuController extends BaseController {
 
             switch (operationCode) {
                 case 1:
-                    ncApi.removeSelfFromRoom(credentials, ApiUtils.getUrlForRemoveSelfFromRoom(currentUser.getBaseUrl
-                            (), conversation.getToken()))
+                    ncApi.leaveRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(currentUser.getBaseUrl(), conversation.getToken()))
                             .subscribeOn(Schedulers.newThread())
                             .observeOn(AndroidSchedulers.mainThread())
                             .retry(1)
@@ -234,7 +233,8 @@ public class OperationsMenuController extends BaseController {
                             .subscribe(operationsObserver);
                     break;
                 case 9:
-                    ncApi.deleteRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(currentUser.getBaseUrl(), conversation.getToken()))
+                    ncApi.deleteRoom(credentials, ApiUtils.getRoom(currentUser.getBaseUrl(),
+                            conversation.getToken()))
                             .subscribeOn(Schedulers.newThread())
                             .observeOn(AndroidSchedulers.mainThread())
                             .retry(1)

+ 1 - 1
app/src/main/java/com/nextcloud/talk/events/EventStatus.java

@@ -35,7 +35,7 @@ public class EventStatus {
     }
 
     public enum EventType {
-        PUSH_REGISTRATION, CAPABILITIES_FETCH, SIGNALING_SETTINGS
+        PUSH_REGISTRATION, CAPABILITIES_FETCH, SIGNALING_SETTINGS, CONVERSATION_UPDATE
     }
 
 }

+ 115 - 0
app/src/main/java/com/nextcloud/talk/jobs/DeleteConversationWorker.java

@@ -0,0 +1,115 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.jobs;
+
+import android.content.Context;
+import androidx.annotation.NonNull;
+import androidx.work.Data;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+import autodagger.AutoInjector;
+import com.nextcloud.talk.api.NcApi;
+import com.nextcloud.talk.application.NextcloudTalkApplication;
+import com.nextcloud.talk.events.EventStatus;
+import com.nextcloud.talk.models.database.UserEntity;
+import com.nextcloud.talk.models.json.generic.GenericOverall;
+import com.nextcloud.talk.utils.ApiUtils;
+import com.nextcloud.talk.utils.bundle.BundleKeys;
+import com.nextcloud.talk.utils.database.user.UserUtils;
+import io.reactivex.Observer;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.JavaNetCookieJar;
+import okhttp3.OkHttpClient;
+import org.greenrobot.eventbus.EventBus;
+import retrofit2.Retrofit;
+
+import javax.inject.Inject;
+import java.net.CookieManager;
+
+@AutoInjector(NextcloudTalkApplication.class)
+public class DeleteConversationWorker extends Worker {
+    @Inject
+    Retrofit retrofit;
+
+    @Inject
+    OkHttpClient okHttpClient;
+
+    @Inject
+    UserUtils userUtils;
+
+    @Inject
+    EventBus eventBus;
+
+    NcApi ncApi;
+
+    public DeleteConversationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+        super(context, workerParams);
+        NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
+    }
+
+    @NonNull
+    @Override
+    public Result doWork() {
+        Data data = getInputData();
+        long operationUserId = data.getLong(BundleKeys.KEY_INTERNAL_USER_ID, -1);
+        String conversationToken = data.getString(BundleKeys.KEY_ROOM_TOKEN);
+        UserEntity operationUser = userUtils.getUserWithId(operationUserId);
+
+        if (operationUser != null) {
+            String credentials = ApiUtils.getCredentials(operationUser.getUsername(), operationUser.getToken());
+            ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
+                    JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
+
+            EventStatus eventStatus = new EventStatus(operationUser.getId(),
+                    EventStatus.EventType.CONVERSATION_UPDATE, true);
+
+            ncApi.deleteRoom(credentials, ApiUtils.getRoom(operationUser.getBaseUrl(), conversationToken))
+                    .subscribeOn(Schedulers.newThread())
+                    .blockingSubscribe(new Observer<GenericOverall>() {
+                        Disposable disposable;
+                        @Override
+                        public void onSubscribe(Disposable d) {
+                            disposable = d;
+
+                        }
+
+                        @Override
+                        public void onNext(GenericOverall genericOverall) {
+                            eventBus.postSticky(eventStatus);
+
+                        }
+
+                        @Override
+                        public void onError(Throwable e) {
+
+                        }
+
+                        @Override
+                        public void onComplete() {
+                            disposable.dispose();
+                        }
+                    });
+        }
+
+        return Result.success();
+    }
+}

+ 115 - 0
app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java

@@ -0,0 +1,115 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.jobs;
+
+import android.content.Context;
+import androidx.annotation.NonNull;
+import androidx.work.Data;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+import autodagger.AutoInjector;
+import com.nextcloud.talk.api.NcApi;
+import com.nextcloud.talk.application.NextcloudTalkApplication;
+import com.nextcloud.talk.events.EventStatus;
+import com.nextcloud.talk.models.database.UserEntity;
+import com.nextcloud.talk.models.json.generic.GenericOverall;
+import com.nextcloud.talk.utils.ApiUtils;
+import com.nextcloud.talk.utils.bundle.BundleKeys;
+import com.nextcloud.talk.utils.database.user.UserUtils;
+import io.reactivex.Observer;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.JavaNetCookieJar;
+import okhttp3.OkHttpClient;
+import org.greenrobot.eventbus.EventBus;
+import retrofit2.Retrofit;
+
+import javax.inject.Inject;
+import java.net.CookieManager;
+
+@AutoInjector(NextcloudTalkApplication.class)
+public class LeaveConversationWorker extends Worker {
+    @Inject
+    Retrofit retrofit;
+
+    @Inject
+    OkHttpClient okHttpClient;
+
+    @Inject
+    UserUtils userUtils;
+
+    @Inject
+    EventBus eventBus;
+
+    NcApi ncApi;
+
+    public LeaveConversationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+        super(context, workerParams);
+        NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
+    }
+
+    @NonNull
+    @Override
+    public Result doWork() {
+        Data data = getInputData();
+        long operationUserId = data.getLong(BundleKeys.KEY_INTERNAL_USER_ID, -1);
+        String conversationToken = data.getString(BundleKeys.KEY_ROOM_TOKEN);
+        UserEntity operationUser = userUtils.getUserWithId(operationUserId);
+
+        if (operationUser != null) {
+            String credentials = ApiUtils.getCredentials(operationUser.getUsername(), operationUser.getToken());
+            ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
+                    JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
+
+            EventStatus eventStatus = new EventStatus(operationUser.getId(),
+                    EventStatus.EventType.CONVERSATION_UPDATE, true);
+
+            ncApi.leaveRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(operationUser.getBaseUrl(), conversationToken))
+                    .subscribeOn(Schedulers.newThread())
+                    .blockingSubscribe(new Observer<GenericOverall>() {
+                        Disposable disposable;
+                        @Override
+                        public void onSubscribe(Disposable d) {
+                            disposable = d;
+
+                        }
+
+                        @Override
+                        public void onNext(GenericOverall genericOverall) {
+                            eventBus.postSticky(eventStatus);
+
+                        }
+
+                        @Override
+                        public void onError(Throwable e) {
+
+                        }
+
+                        @Override
+                        public void onComplete() {
+                            disposable.dispose();
+                        }
+                    });
+        }
+
+        return Result.success();
+    }
+}

+ 2 - 2
app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsJob.java → app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java

@@ -46,7 +46,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 @AutoInjector(NextcloudTalkApplication.class)
-public class SignalingSettingsJob extends Worker {
+public class SignalingSettingsWorker extends Worker {
     private static final String TAG = "SignalingSettingsJob";
 
     @Inject
@@ -58,7 +58,7 @@ public class SignalingSettingsJob extends Worker {
     @Inject
     EventBus eventBus;
 
-    public SignalingSettingsJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+    public SignalingSettingsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
         super(context, workerParams);
     }
 

+ 2 - 0
app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java

@@ -22,12 +22,14 @@ package com.nextcloud.talk.utils;
 import android.net.Uri;
 
 import android.text.TextUtils;
+import androidx.annotation.DimenRes;
 import com.nextcloud.talk.BuildConfig;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.models.RetrofitBucket;
 import okhttp3.Credentials;
 
+import javax.annotation.Nullable;
 import java.util.HashMap;
 import java.util.Map;
 

+ 1 - 1
app/src/main/res/drawable/ic_star_grey600_24dp.xml → app/src/main/res/drawable/ic_delete_black_24dp.xml

@@ -21,5 +21,5 @@
 <vector android:autoMirrored="true" android:height="24dp"
     android:viewportHeight="24.0" android:viewportWidth="24.0"
     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
-    <path android:fillColor="#757575" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
+    <path android:fillColor="#FF000000" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
 </vector>

+ 1 - 1
app/src/main/res/drawable/ic_star_border_grey600_24dp.xml → app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml

@@ -21,5 +21,5 @@
 <vector android:autoMirrored="true" android:height="24dp"
     android:viewportHeight="24.0" android:viewportWidth="24.0"
     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
-    <path android:fillColor="#757575" android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
+    <path android:fillColor="#FF000000" android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
 </vector>

+ 25 - 0
app/src/main/res/drawable/ic_star_black_24dp.xml

@@ -0,0 +1,25 @@
+<!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Mario Danic
+  ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+  ~
+  ~ 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 <http://www.gnu.org/licenses/>.
+  -->
+
+<vector android:autoMirrored="true" android:height="24dp"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
+</vector>

+ 25 - 0
app/src/main/res/drawable/ic_star_border_black_24dp.xml

@@ -0,0 +1,25 @@
+<!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Mario Danic
+  ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+  ~
+  ~ 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 <http://www.gnu.org/licenses/>.
+  -->
+
+<vector android:autoMirrored="true" android:height="24dp"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
+</vector>

+ 1 - 1
app/src/main/res/drawable/shape_favorite_bubble.xml

@@ -26,5 +26,5 @@
             <solid android:color="@color/white"/>
         </shape>
     </item>
-    <item android:drawable="@drawable/ic_star_grey600_24dp"/>
+    <item android:drawable="@drawable/ic_star_black_24dp" android:tint="@color/grey_600"/>
 </layer-list>

+ 45 - 1
app/src/main/res/layout/controller_conversation_info.xml

@@ -76,11 +76,30 @@
                 </RelativeLayout>
             </com.yarolegovich.mp.MaterialPreferenceCategory>
 
+            <com.yarolegovich.mp.MaterialPreferenceCategory
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/conversation_info_name"
+                android:id="@+id/otherRoomOptions"
+                android:visibility="gone">
+
+                <com.yarolegovich.mp.MaterialStandardPreference
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    apc:mp_icon="@drawable/ic_star_black_24dp"
+                    apc:mp_icon_tint="@color/grey_600"
+                    apc:mp_title="@string/nc_add_to_favorites"
+                    android:id="@+id/favoriteConversationAction">
+                    
+                </com.yarolegovich.mp.MaterialStandardPreference>
+
+            </com.yarolegovich.mp.MaterialPreferenceCategory>
+
             <include
                 layout="@layout/notification_settings_item"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_below="@id/conversation_info_name"
+                android:layout_below="@id/otherRoomOptions"
                 android:visibility="gone" />
 
             <com.yarolegovich.mp.MaterialPreferenceCategory
@@ -100,6 +119,31 @@
                     tools:listitem="@layout/rv_item_contact"></androidx.recyclerview.widget.RecyclerView>
 
             </com.yarolegovich.mp.MaterialPreferenceCategory>
+            
+            <com.yarolegovich.mp.MaterialPreferenceCategory
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/participants_list_category"
+                android:visibility="gone"
+                android:id="@+id/ownOptions">
+
+                <com.yarolegovich.mp.MaterialStandardPreference
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    apc:mp_title="@string/nc_leave"
+                    apc:mp_icon="@drawable/ic_exit_to_app_black_24dp"
+                    apc:mp_icon_tint="@color/grey_600"
+                    android:id="@+id/leaveConversationAction" />
+
+                <com.yarolegovich.mp.MaterialStandardPreference
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    apc:mp_title="@string/nc_delete_call"
+                    apc:mp_icon_tint="@color/grey_600"
+                    apc:mp_icon="@drawable/ic_delete_black_24dp"
+                    android:id="@+id/deleteConversationAction" />
+
+            </com.yarolegovich.mp.MaterialPreferenceCategory>
         </RelativeLayout>
     </ScrollView>
 </RelativeLayout>