diff --git a/app/build.gradle b/app/build.gradle index 5378806d4..3c42229a9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,13 +11,13 @@ versioning { version = versioning.name android { - compileSdkVersion 26 - buildToolsVersion '26.0.2' + compileSdkVersion 27 + buildToolsVersion '27.0.0' defaultConfig { applicationId "com.nextcloud.talk" versionName version minSdkVersion 21 - targetSdkVersion 26 + targetSdkVersion 27 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" // Enabling multidex support. @@ -52,7 +52,7 @@ android { } ext { - supportLibraryVersion = '26.1.0' + supportLibraryVersion = '27.0.0' googleLibraryVersion = '11.6.0' } @@ -141,6 +141,8 @@ dependencies { implementation 'ru.alexbykov:nopermission:1.1.1' implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.7' + implementation 'com.github.Kennyc1012:BottomSheet:2.4.0' + testImplementation 'junit:junit:4.12' androidTestImplementation ('com.android.support.test.espresso:espresso-core:3.0.1', { exclude group: 'com.android.support', module: 'support-annotations' diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index f2a3852de..b00d0f4f6 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -764,5 +764,4 @@ public class CallActivity extends AppCompatActivity { } }); } - } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/RoomItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/CallItem.java similarity index 91% rename from app/src/main/java/com/nextcloud/talk/adapters/items/RoomItem.java rename to app/src/main/java/com/nextcloud/talk/adapters/items/CallItem.java index de5681ee4..3d1a71579 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/RoomItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/CallItem.java @@ -23,6 +23,7 @@ package com.nextcloud.talk.adapters.items; import android.text.TextUtils; import android.text.format.DateUtils; import android.view.View; +import android.widget.ImageButton; import android.widget.TextView; import com.bumptech.glide.load.engine.DiskCacheStrategy; @@ -32,10 +33,13 @@ import com.nextcloud.talk.R; import com.nextcloud.talk.api.helpers.api.ApiHelper; import com.nextcloud.talk.api.models.json.rooms.Room; import com.nextcloud.talk.application.NextcloudTalkApplication; +import com.nextcloud.talk.events.MoreMenuClickEvent; import com.nextcloud.talk.persistence.entities.UserEntity; import com.nextcloud.talk.utils.ColorUtils; import com.nextcloud.talk.utils.glide.GlideApp; +import org.greenrobot.eventbus.EventBus; + import java.util.List; import butterknife.BindView; @@ -47,20 +51,20 @@ import eu.davidea.flexibleadapter.items.IFilterable; import eu.davidea.flexibleadapter.utils.FlexibleUtils; import eu.davidea.viewholders.FlexibleViewHolder; -public class RoomItem extends AbstractFlexibleItem implements IFilterable { +public class CallItem extends AbstractFlexibleItem implements IFilterable { private Room room; private UserEntity userEntity; - public RoomItem(Room room, UserEntity userEntity) { + public CallItem(Room room, UserEntity userEntity) { this.room = room; this.userEntity = userEntity; } @Override public boolean equals(Object o) { - if (o instanceof RoomItem) { - RoomItem inItem = (RoomItem) o; + if (o instanceof CallItem) { + CallItem inItem = (CallItem) o; return room.equals(inItem.getModel()); } return false; @@ -148,6 +152,8 @@ public class RoomItem extends AbstractFlexibleItem holder.avatarImageView.setVisibility(View.GONE); } + + holder.moreMenuButton.setOnClickListener(view -> EventBus.getDefault().post(new MoreMenuClickEvent(room))); } @Override @@ -165,6 +171,8 @@ public class RoomItem extends AbstractFlexibleItem public TextView roomLastPing; @BindView(R.id.avatar_image) public AvatarImageView avatarImageView; + @BindView(R.id.more_menu) + public ImageButton moreMenuButton; /** * Default constructor. diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/MenuItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/MenuItem.java new file mode 100644 index 000000000..2687a8132 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/MenuItem.java @@ -0,0 +1,90 @@ +/* + * Nextcloud Talk application + * + * @author Mario Danic + * Copyright (C) 2017 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.adapters.items; + + +import android.view.View; +import android.widget.TextView; + +import com.nextcloud.talk.R; +import com.nextcloud.talk.events.MenuItemClickEvent; + +import org.greenrobot.eventbus.EventBus; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import eu.davidea.flexibleadapter.FlexibleAdapter; +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem; +import eu.davidea.viewholders.FlexibleViewHolder; + +public class MenuItem extends AbstractFlexibleItem { + private String title; + + public MenuItem(String title) { + this.title = title; + } + + @Override + public boolean equals(Object o) { + if (o instanceof MenuItem) { + MenuItem inItem = (MenuItem) o; + return title.equals(inItem.getModel()); + } + return false; + } + + private String getModel() { + return title; + } + + @Override + public int getLayoutRes() { + return R.layout.rv_item_menu; + } + + @Override + public MenuItem.MenuItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) { + return new MenuItemViewHolder(view, adapter); + } + + @Override + public void bindViewHolder(FlexibleAdapter adapter, MenuItem.MenuItemViewHolder holder, int position, List payloads) { + holder.menuTitle.setText(title); + + holder.menuTitle.setOnClickListener(view -> EventBus.getDefault().post(new MenuItemClickEvent(title))); + } + + static class MenuItemViewHolder extends FlexibleViewHolder { + + @BindView(R.id.menu_text) + public TextView menuTitle; + + /** + * Default constructor. + */ + MenuItemViewHolder(View view, FlexibleAdapter adapter) { + super(view, adapter); + ButterKnife.bind(this, view); + } + } +} diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java index 8d6136d0e..360ef5ecb 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java @@ -28,7 +28,7 @@ import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.load.model.LazyHeaders; import com.nextcloud.talk.R; import com.nextcloud.talk.api.helpers.api.ApiHelper; -import com.nextcloud.talk.api.models.User; +import com.nextcloud.talk.api.models.json.participants.Participant; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.persistence.entities.UserEntity; import com.nextcloud.talk.utils.ColorUtils; @@ -47,11 +47,11 @@ import eu.davidea.viewholders.FlexibleViewHolder; public class UserItem extends AbstractFlexibleItem implements IFilterable { - private User user; + private Participant participant; private UserEntity userEntity; - public UserItem(User user, UserEntity userEntity) { - this.user = user; + public UserItem(Participant participant, UserEntity userEntity) { + this.participant = participant; this.userEntity = userEntity; } @@ -59,22 +59,22 @@ public class UserItem extends AbstractFlexibleItem public boolean equals(Object o) { if (o instanceof UserItem) { UserItem inItem = (UserItem) o; - return user.equals(inItem.getModel()); + return participant.equals(inItem.getModel()); } return false; } @Override public int hashCode() { - return user.hashCode(); + return participant.hashCode(); } /** * @return the model object */ - public User getModel() { - return user; + public Participant getModel() { + return participant; } public UserEntity getEntity() { @@ -94,17 +94,17 @@ public class UserItem extends AbstractFlexibleItem @Override public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) { if (adapter.hasSearchText()) { - FlexibleUtils.highlightText(holder.contactDisplayName, user.getName(), adapter.getSearchText()); + FlexibleUtils.highlightText(holder.contactDisplayName, participant.getName(), adapter.getSearchText()); } else { - holder.contactDisplayName.setText(user.getName()); + holder.contactDisplayName.setText(participant.getName()); } // Awful hack - holder.avatarImageView.setTextAndColorSeed(String.valueOf(user.getName(). + holder.avatarImageView.setTextAndColorSeed(String.valueOf(participant.getName(). toUpperCase().charAt(0)), ColorUtils.colorSeed); GlideUrl glideUrl = new GlideUrl(ApiHelper.getUrlForAvatarWithName(userEntity.getBaseUrl(), - user.getUserId()), new LazyHeaders.Builder() + participant.getUserId()), new LazyHeaders.Builder() .setHeader("Accept", "image/*") .setHeader("User-Agent", ApiHelper.getUserAgent()) .build()); @@ -121,7 +121,7 @@ public class UserItem extends AbstractFlexibleItem @Override public boolean filter(String constraint) { - return user.getName() != null && user.getName().toLowerCase().trim().contains(constraint.toLowerCase()); + return participant.getName() != null && participant.getName().toLowerCase().trim().contains(constraint.toLowerCase()); } diff --git a/app/src/main/java/com/nextcloud/talk/api/models/User.java b/app/src/main/java/com/nextcloud/talk/api/models/User.java deleted file mode 100644 index 409651114..000000000 --- a/app/src/main/java/com/nextcloud/talk/api/models/User.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * Nextcloud Talk application - * - * @author Mario Danic - * Copyright (C) 2017 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 . - */ -package com.nextcloud.talk.api.models; - -import com.bluelinelabs.logansquare.annotation.JsonField; -import com.bluelinelabs.logansquare.annotation.JsonObject; - -import org.parceler.Parcel; - -import lombok.Data; - -@Parcel -@Data -@JsonObject -public class User { - @JsonField(name = "userId") - String userId; - @JsonField(name = "type") - int type; - @JsonField(name = "name") - String name; -} diff --git a/app/src/main/java/com/nextcloud/talk/api/models/json/converters/EnumParticipantTypeConverter.java b/app/src/main/java/com/nextcloud/talk/api/models/json/converters/EnumParticipantTypeConverter.java new file mode 100644 index 000000000..6154f8b91 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/api/models/json/converters/EnumParticipantTypeConverter.java @@ -0,0 +1,65 @@ +/* + * Nextcloud Talk application + * + * @author Mario Danic + * Copyright (C) 2017 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.api.models.json.converters; + +import com.bluelinelabs.logansquare.typeconverters.IntBasedTypeConverter; +import com.nextcloud.talk.api.models.json.participants.Participant; + +public class EnumParticipantTypeConverter extends IntBasedTypeConverter { + @Override + public Participant.ParticipantType getFromInt(int i) { + switch (i) { + case 1: + return Participant.ParticipantType.OWNER; + case 2: + return Participant.ParticipantType.MODERATOR; + case 3: + return Participant.ParticipantType.USER; + case 4: + return Participant.ParticipantType.GUEST; + case 5: + return Participant.ParticipantType.USER_FOLLOWING_LINK; + default: + return Participant.ParticipantType.DUMMY; + } + + } + + @Override + public int convertToInt(Participant.ParticipantType object) { + switch (object) { + case DUMMY: + return 0; + case OWNER: + return 1; + case MODERATOR: + return 2; + case USER: + return 3; + case GUEST: + return 4; + case USER_FOLLOWING_LINK: + return 5; + default: + return 0; + } + } +} diff --git a/app/src/main/java/com/nextcloud/talk/api/models/json/participants/Participant.java b/app/src/main/java/com/nextcloud/talk/api/models/json/participants/Participant.java index 7a68ffcf9..0859eb851 100644 --- a/app/src/main/java/com/nextcloud/talk/api/models/json/participants/Participant.java +++ b/app/src/main/java/com/nextcloud/talk/api/models/json/participants/Participant.java @@ -34,6 +34,12 @@ public class Participant { @JsonField(name = "userId") String userId; + @JsonField(name = "type") + ParticipantType type; + + @JsonField(name = "name") + String name; + @JsonField(name = "lastPing") long lastPing; @@ -45,4 +51,13 @@ public class Participant { @JsonField(name = "inCall") boolean inCall; + + public enum ParticipantType { + DUMMY, + OWNER, + MODERATOR, + USER, + GUEST, + USER_FOLLOWING_LINK + } } diff --git a/app/src/main/java/com/nextcloud/talk/api/models/json/rooms/Room.java b/app/src/main/java/com/nextcloud/talk/api/models/json/rooms/Room.java index 2cfbfaeb4..614b39548 100644 --- a/app/src/main/java/com/nextcloud/talk/api/models/json/rooms/Room.java +++ b/app/src/main/java/com/nextcloud/talk/api/models/json/rooms/Room.java @@ -22,8 +22,9 @@ package com.nextcloud.talk.api.models.json.rooms; import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonObject; -import com.nextcloud.talk.api.models.User; +import com.nextcloud.talk.api.models.json.converters.EnumParticipantTypeConverter; import com.nextcloud.talk.api.models.json.converters.EnumRoomTypeConverter; +import com.nextcloud.talk.api.models.json.participants.Participant; import org.parceler.Parcel; @@ -52,9 +53,11 @@ public class Room { @JsonField(name = "numGuests") public long numberOfGuests; @JsonField(name = "guestList") - public List guestList; + public List guestList; @JsonField(name = "participants") - public List participants; + public List participants; + @JsonField(name = "participantType", typeConverter = EnumParticipantTypeConverter.class) + public Participant.ParticipantType participantType; @JsonField(name = "hasPassword") public boolean hasPassword; @JsonField(name = "sessionId") @@ -66,4 +69,22 @@ public class Room { ROOM_GROUP_CALL, ROOM_PUBLIC_CALL } + + public boolean isPublic() { + return (RoomType.ROOM_PUBLIC_CALL.equals(type)); + } + + public boolean canModerate() { + return (Participant.ParticipantType.OWNER.equals(participantType) + || Participant.ParticipantType.MODERATOR.equals(participantType)); + } + + public boolean isNameEditable() { + return (canModerate() && !RoomType.ROOM_TYPE_ONE_TO_ONE_CALL.equals(type)); + } + + public boolean isDeletable() { + return (canModerate() && ((participants != null && participants.size() > 2) || numberOfGuests > 0)); + } + } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallsListController.java index c531319d9..0a609b93c 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/CallsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/CallsListController.java @@ -49,17 +49,23 @@ import com.bluelinelabs.conductor.RouterTransaction; import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler; import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler; import com.bluelinelabs.conductor.internal.NoOpControllerChangeHandler; +import com.kennyc.bottomsheet.BottomSheet; import com.nextcloud.talk.R; import com.nextcloud.talk.activities.CallActivity; -import com.nextcloud.talk.adapters.items.RoomItem; +import com.nextcloud.talk.adapters.items.CallItem; import com.nextcloud.talk.api.NcApi; import com.nextcloud.talk.api.helpers.api.ApiHelper; +import com.nextcloud.talk.api.models.json.rooms.Room; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.controllers.base.BaseController; +import com.nextcloud.talk.events.MoreMenuClickEvent; import com.nextcloud.talk.persistence.entities.UserEntity; import com.nextcloud.talk.utils.bundle.BundleBuilder; import com.nextcloud.talk.utils.database.user.UserUtils; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import org.parceler.Parcels; import java.util.ArrayList; @@ -87,6 +93,9 @@ public class CallsListController extends BaseController implements SearchView.On @Inject UserUtils userUtils; + @Inject + EventBus eventBus; + @Inject NcApi ncApi; @BindView(R.id.recycler_view) @@ -97,9 +106,10 @@ public class CallsListController extends BaseController implements SearchView.On private UserEntity userEntity; private Disposable roomsQueryDisposable; - private FlexibleAdapter adapter; - private List roomItems = new ArrayList<>(); + private FlexibleAdapter adapter; + private List callItems = new ArrayList<>(); + private BottomSheet bottomSheet; private MenuItem searchItem; private SearchView searchView; private String searchQuery; @@ -108,13 +118,13 @@ public class CallsListController extends BaseController implements SearchView.On new FlexibleAdapter.OnItemClickListener() { @Override public boolean onItemClick(int position) { - if (roomItems.size() > position) { + if (callItems.size() > position) { overridePushHandler(new NoOpControllerChangeHandler()); overridePopHandler(new NoOpControllerChangeHandler()); - RoomItem roomItem = roomItems.get(position); + CallItem callItem = callItems.get(position); Intent callIntent = new Intent(getActivity(), CallActivity.class); BundleBuilder bundleBuilder = new BundleBuilder(new Bundle()); - bundleBuilder.putString("roomToken", roomItem.getModel().getToken()); + bundleBuilder.putString("roomToken", callItem.getModel().getToken()); bundleBuilder.putParcelable("userEntity", Parcels.wrap(userEntity)); callIntent.putExtras(bundleBuilder.build()); startActivity(callIntent); @@ -142,7 +152,7 @@ public class CallsListController extends BaseController implements SearchView.On userEntity = userUtils.getCurrentUser(); if (adapter == null) { - adapter = new FlexibleAdapter<>(roomItems, getActivity(), false); + adapter = new FlexibleAdapter<>(callItems, getActivity(), false); if (userEntity != null) { fetchData(); } @@ -160,6 +170,17 @@ public class CallsListController extends BaseController implements SearchView.On } } + @Override + protected void onAttach(@NonNull View view) { + super.onAttach(view); + eventBus.register(this); + } + + @Override + protected void onDetach(@NonNull View view) { + super.onDetach(view); + eventBus.unregister(this); + } private void initSearchView() { if (getActivity() != null) { @@ -198,7 +219,7 @@ public class CallsListController extends BaseController implements SearchView.On } else { handler.postDelayed(() -> { bottomNavigationView.setVisibility(View.VISIBLE); - searchItem.setVisible(roomItems.size() > 0); + searchItem.setVisible(callItems.size() > 0); }, 500); } @@ -221,7 +242,7 @@ public class CallsListController extends BaseController implements SearchView.On @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - searchItem.setVisible(roomItems.size() > 0); + searchItem.setVisible(callItems.size() > 0); if (adapter.hasSearchText()) { searchItem.expandActionView(); searchView.setQuery(adapter.getSearchText(), false); @@ -231,7 +252,7 @@ public class CallsListController extends BaseController implements SearchView.On private void fetchData() { dispose(null); - roomItems = new ArrayList<>(); + callItems = new ArrayList<>(); roomsQueryDisposable = ncApi.getRooms(ApiHelper.getCredentials(userEntity.getUsername(), userEntity.getToken()), ApiHelper.getUrlForGetRooms(userEntity.getBaseUrl())) @@ -241,18 +262,21 @@ public class CallsListController extends BaseController implements SearchView.On if (roomsOverall != null) { for (int i = 0; i < roomsOverall.getOcs().getData().size(); i++) { - roomItems.add(new RoomItem(roomsOverall.getOcs().getData().get(i), userEntity)); + callItems.add(new CallItem(roomsOverall.getOcs().getData().get(i), userEntity)); } - adapter.updateDataSet(roomItems, true); + adapter.updateDataSet(callItems, true); - Collections.sort(roomItems, (roomItem, t1) -> - Long.compare(t1.getModel().getLastPing(), roomItem.getModel().getLastPing())); + Collections.sort(callItems, (callItem, t1) -> + Long.compare(t1.getModel().getLastPing(), callItem.getModel().getLastPing())); if (searchItem != null) { - searchItem.setVisible(roomItems.size() > 0); + searchItem.setVisible(callItems.size() > 0); } } + + swipeRefreshLayout.setRefreshing(false); + }, throwable -> { if (searchItem != null) { searchItem.setVisible(false); @@ -275,6 +299,7 @@ public class CallsListController extends BaseController implements SearchView.On break; } } + swipeRefreshLayout.setRefreshing(false); dispose(roomsQueryDisposable); }, () -> { dispose(roomsQueryDisposable); @@ -358,4 +383,25 @@ public class CallsListController extends BaseController implements SearchView.On return onQueryTextChange(query); } + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(MoreMenuClickEvent moreMenuClickEvent) { + BundleBuilder bundleBuilder = new BundleBuilder(new Bundle()); + Room room = moreMenuClickEvent.getRoom(); + bundleBuilder.putParcelable("room", Parcels.wrap(room)); + + View view = getActivity().getLayoutInflater().inflate(R.layout.bottom_sheet, null, false); + + getChildRouter((ViewGroup) view).setRoot( + RouterTransaction.with(new RoomMenuController(bundleBuilder.build())) + .popChangeHandler(new HorizontalChangeHandler()) + .pushChangeHandler(new HorizontalChangeHandler())); + + if (bottomSheet == null) { + bottomSheet = new BottomSheet.Builder(getActivity()).setView(view).create(); + } + + bottomSheet.show(); + } + + } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java index aa0a7082d..c9bae2785 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java @@ -51,7 +51,7 @@ import com.nextcloud.talk.R; import com.nextcloud.talk.adapters.items.UserItem; import com.nextcloud.talk.api.NcApi; import com.nextcloud.talk.api.helpers.api.ApiHelper; -import com.nextcloud.talk.api.models.User; +import com.nextcloud.talk.api.models.json.participants.Participant; import com.nextcloud.talk.api.models.json.sharees.Sharee; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.controllers.base.BaseController; @@ -239,13 +239,13 @@ public class ContactsController extends BaseController implements SearchView.OnQ getExactUsers().getExactSharees()); } - User user; + Participant participant; for (Sharee sharee : shareeHashSet) { if (!sharee.getValue().getShareWith().equals(userEntity.getUsername())) { - user = new User(); - user.setName(sharee.getLabel()); - user.setUserId(sharee.getValue().getShareWith()); - contactItems.add(new UserItem(user, userEntity)); + participant = new Participant(); + participant.setName(sharee.getLabel()); + participant.setUserId(sharee.getValue().getShareWith()); + contactItems.add(new UserItem(participant, userEntity)); } } @@ -255,6 +255,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ adapter.updateDataSet(contactItems, true); searchItem.setVisible(contactItems.size() > 0); + swipeRefreshLayout.setRefreshing(false); } }, throwable -> { @@ -280,6 +281,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ } } + swipeRefreshLayout.setRefreshing(false); dispose(contactsQueryDisposable); } , () -> { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/RoomMenuController.java b/app/src/main/java/com/nextcloud/talk/controllers/RoomMenuController.java new file mode 100644 index 000000000..d1db24eb8 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/controllers/RoomMenuController.java @@ -0,0 +1,121 @@ +/* + * Nextcloud Talk application + * + * @author Mario Danic + * Copyright (C) 2017 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.controllers; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.nextcloud.talk.R; +import com.nextcloud.talk.adapters.items.MenuItem; +import com.nextcloud.talk.api.models.json.rooms.Room; +import com.nextcloud.talk.application.NextcloudTalkApplication; +import com.nextcloud.talk.controllers.base.BaseController; + +import org.parceler.Parcels; + +import java.util.ArrayList; +import java.util.List; + +import autodagger.AutoInjector; +import butterknife.BindView; +import eu.davidea.flexibleadapter.FlexibleAdapter; +import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager; +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem; + +@AutoInjector(NextcloudTalkApplication.class) +public class RoomMenuController extends BaseController { + private Room room; + + @BindView(R.id.recycler_view) + RecyclerView recyclerView; + + private List menuItems; + private FlexibleAdapter adapter; + + public RoomMenuController(Bundle args) { + super(args); + this.room = Parcels.unwrap(args.getParcelable("room")); + } + + @Override + protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) { + return inflater.inflate(R.layout.controller_room_menu, container, false); + } + + @Override + protected void onViewBound(@NonNull View view) { + super.onViewBound(view); + NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this); + prepareViews(); + } + + private void prepareViews() { + LinearLayoutManager layoutManager = new SmoothScrollLinearLayoutManager(getActivity()); + recyclerView.setLayoutManager(layoutManager); + recyclerView.setHasFixedSize(true); + + prepareMenu(); + if (adapter == null) { + adapter = new FlexibleAdapter<>(menuItems, getActivity(), false); + } + + recyclerView.setAdapter(adapter); + + recyclerView.addItemDecoration(new DividerItemDecoration( + recyclerView.getContext(), + layoutManager.getOrientation() + )); + } + + private void prepareMenu() { + menuItems = new ArrayList<>(); + menuItems.add(new MenuItem(getResources().getString(R.string.nc_leave))); + + if (room.isNameEditable()) { + menuItems.add(new MenuItem(getResources().getString(R.string.nc_rename))); + } + + if (!room.isPublic()) { + menuItems.add(new MenuItem(getResources().getString(R.string.nc_make_call_public))); + } else { + if (room.isHasPassword()) { + menuItems.add(new MenuItem(getResources().getString(R.string.nc_change_password))); + } else { + menuItems.add(new MenuItem(getResources().getString(R.string.nc_set_password))); + } + + menuItems.add(new MenuItem(getResources().getString(R.string.nc_share_link))); + menuItems.add(new MenuItem(getResources().getString(R.string.nc_stop_sharing))); + + } + + if (room.isDeletable()) { + menuItems.add(new MenuItem(getResources().getString(R.string.nc_delete_call))); + } + } + +} diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.java b/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.java index bf038df94..3199eb6f7 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.java @@ -31,7 +31,7 @@ import android.view.ViewGroup; import com.nextcloud.talk.R; import com.nextcloud.talk.adapters.items.UserItem; -import com.nextcloud.talk.api.models.User; +import com.nextcloud.talk.api.models.json.participants.Participant; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.controllers.base.BaseController; import com.nextcloud.talk.persistence.entities.UserEntity; @@ -115,15 +115,15 @@ public class SwitchAccountController extends BaseController { adapter = new FlexibleAdapter<>(userItems, getActivity(), false); UserEntity userEntity; - User user; + Participant participant; for (Object userEntityObject : userUtils.getUsers()) { userEntity = (UserEntity) userEntityObject; if (!userEntity.getCurrent()) { - user = new User(); - user.setName(userEntity.getDisplayName()); - user.setUserId(userEntity.getUsername()); - userItems.add(new UserItem(user, userEntity)); + participant = new Participant(); + participant.setName(userEntity.getDisplayName()); + participant.setUserId(userEntity.getUsername()); + userItems.add(new UserItem(participant, userEntity)); } } diff --git a/app/src/main/java/com/nextcloud/talk/events/MenuItemClickEvent.java b/app/src/main/java/com/nextcloud/talk/events/MenuItemClickEvent.java new file mode 100644 index 000000000..30fe63f9b --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/events/MenuItemClickEvent.java @@ -0,0 +1,29 @@ +/* + * Nextcloud Talk application + * + * @author Mario Danic + * Copyright (C) 2017 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.events; + +public class MenuItemClickEvent { + private String menuTitle; + + public MenuItemClickEvent(String menuTitle) { + this.menuTitle = menuTitle; + } +} diff --git a/app/src/main/java/com/nextcloud/talk/events/MoreMenuClickEvent.java b/app/src/main/java/com/nextcloud/talk/events/MoreMenuClickEvent.java new file mode 100644 index 000000000..da0101e1a --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/events/MoreMenuClickEvent.java @@ -0,0 +1,34 @@ +/* + * Nextcloud Talk application + * + * @author Mario Danic + * Copyright (C) 2017 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.events; + +import com.nextcloud.talk.api.models.json.rooms.Room; + +import lombok.Data; + +@Data +public class MoreMenuClickEvent { + private final Room room; + + public MoreMenuClickEvent(Room room) { + this.room = room; + } +} diff --git a/app/src/main/res/drawable/ic_more_horiz_black_24dp.xml b/app/src/main/res/drawable/ic_more_horiz_black_24dp.xml new file mode 100644 index 000000000..0a5f522d4 --- /dev/null +++ b/app/src/main/res/drawable/ic_more_horiz_black_24dp.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/app/src/main/res/layout/bottom_sheet.xml b/app/src/main/res/layout/bottom_sheet.xml new file mode 100644 index 000000000..5d39d03a9 --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/controller_room_menu.xml b/app/src/main/res/layout/controller_room_menu.xml new file mode 100644 index 000000000..b62d8a979 --- /dev/null +++ b/app/src/main/res/layout/controller_room_menu.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/rv_item_call.xml b/app/src/main/res/layout/rv_item_call.xml index aedbab36d..1eeffb8e5 100644 --- a/app/src/main/res/layout/rv_item_call.xml +++ b/app/src/main/res/layout/rv_item_call.xml @@ -32,7 +32,7 @@ android:layout_width="@dimen/avatar_size" android:layout_height="@dimen/avatar_size" android:layout_centerVertical="true" - android:layout_marginEnd="@dimen/activity_horizontal_margin" + android:layout_marginEnd="@dimen/margin_between_elements" android:layout_marginStart="@dimen/activity_horizontal_margin" android:scaleType="centerInside" app:aiv_CornerRadius="@dimen/avatar_corner_radius" @@ -40,11 +40,12 @@ app:aiv_TextSizeRatio="0.5"/> + + diff --git a/app/src/main/res/layout/rv_item_menu.xml b/app/src/main/res/layout/rv_item_menu.xml new file mode 100644 index 000000000..5d9b6f486 --- /dev/null +++ b/app/src/main/res/layout/rv_item_menu.xml @@ -0,0 +1,33 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d05ebad05..bc3e71c35 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,4 +60,16 @@ GNU General Public License, Version 3 Select an account + + + What would you like to do? + Leave call + Rename call + Set the password + Change the password + Share link + Make call public + Stop sharing the call + Delete call + diff --git a/build.gradle b/build.gradle index 881f21e4f..d06c119b9 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ buildscript { maven { url "http://dl.bintray.com/davideas/maven" } } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0' + classpath 'com.android.tools.build:gradle:3.0.1' classpath 'eu.davidea:grabver:0.6.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" classpath 'com.google.gms:google-services:3.1.0'