Merge pull request #2189 from nextcloud/chore/1549/roomMigration1

Room migration - Part 1
This commit is contained in:
Andy Scherzinger 2022-07-13 16:12:51 +02:00 committed by GitHub
commit eb3cebab1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 350 additions and 273 deletions

View file

@ -87,6 +87,7 @@ import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOveral
import com.nextcloud.talk.ui.dialog.AudioOutputDialog;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.DisplayUtils;
import com.nextcloud.talk.utils.LegacyUserEntityMapper;
import com.nextcloud.talk.utils.NotificationUtils;
import com.nextcloud.talk.utils.animations.PulseAnimation;
import com.nextcloud.talk.utils.bundle.BundleKeys;
@ -1352,7 +1353,8 @@ public class CallActivity extends CallBaseActivity {
ApplicationWideCurrentRoomHolder.getInstance().setSession(callSession);
ApplicationWideCurrentRoomHolder.getInstance().setCurrentRoomId(roomId);
ApplicationWideCurrentRoomHolder.getInstance().setCurrentRoomToken(roomToken);
ApplicationWideCurrentRoomHolder.getInstance().setUserInRoom(conversationUser);
ApplicationWideCurrentRoomHolder.getInstance().setUserInRoom(
LegacyUserEntityMapper.toModel(conversationUser));
callOrJoinRoomViaWebSocket();
}
@ -1415,7 +1417,7 @@ public class CallActivity extends CallBaseActivity {
if (!TextUtils.isEmpty(roomToken)) {
NotificationUtils.INSTANCE.cancelExistingNotificationsForRoom(getApplicationContext(),
conversationUser,
Objects.requireNonNull(LegacyUserEntityMapper.toModel(conversationUser)),
roomToken);
}

View file

@ -335,7 +335,7 @@ public class CallNotificationActivity extends CallBaseActivity {
DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForAvatar(userBeingCalled.getBaseUrl(),
currentConversation.getName(),
true), null);
true));
ImagePipeline imagePipeline = Fresco.getImagePipeline();
DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null);

View file

@ -124,7 +124,7 @@ public class ParticipantsAdapter extends BaseAdapter {
imageView.setController(null);
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setOldController(imageView.getController())
.setImageRequest(DisplayUtils.getImageRequestForUrl(participantDisplayItem.getUrlForAvatar(), null))
.setImageRequest(DisplayUtils.getImageRequestForUrl(participantDisplayItem.getUrlForAvatar()))
.build();
imageView.setController(draweeController);
}

View file

@ -23,18 +23,18 @@ package com.nextcloud.talk.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ReactionItemBinding
import com.nextcloud.talk.models.database.UserEntity
class ReactionsAdapter(
private val clickListener: ReactionItemClickListener,
private val userEntity: UserEntity?
private val user: User?
) : RecyclerView.Adapter<ReactionsViewHolder>() {
internal var list: MutableList<ReactionItem> = ArrayList<ReactionItem>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReactionsViewHolder {
val itemBinding = ReactionItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ReactionsViewHolder(itemBinding, userEntity?.baseUrl)
return ReactionsViewHolder(itemBinding, user?.baseUrl)
}
override fun onBindViewHolder(holder: ReactionsViewHolder, position: Int) {

View file

@ -61,8 +61,7 @@ class ReactionsViewHolder(
baseUrl,
displayName,
false
),
null
)
)
)
.build()
@ -77,8 +76,7 @@ class ReactionsViewHolder(
baseUrl,
reactionItem.reactionVoter.actorId,
false
),
null
)
)
)
.build()

View file

@ -141,8 +141,7 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
ApiUtils.getUrlForAvatar(
userEntity.getBaseUrl(),
participant.getCalculatedActorId(),
true),
null))
true)))
.build();
holder.binding.userIcon.setController(draweeController);
}

View file

@ -181,8 +181,7 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
.setImageRequest(DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForGuestAvatar(userEntity.getBaseUrl(),
displayName,
false),
null))
false)))
.build();
holder.binding.avatarDraweeView.setController(draweeController);
@ -194,8 +193,7 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
.setImageRequest(DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForAvatar(userEntity.getBaseUrl(),
participant.getCalculatedActorId(),
false),
null))
false)))
.build();
holder.binding.avatarDraweeView.setController(draweeController);
}

View file

@ -35,21 +35,20 @@ import android.os.Build;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.view.View;
import android.widget.ImageView;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.nextcloud.talk.R;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.databinding.RvItemConversationWithLastMessageBinding;
import com.nextcloud.talk.models.database.CapabilitiesUtil;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.chat.ChatMessage;
import com.nextcloud.talk.models.json.conversations.Conversation;
import com.nextcloud.talk.models.json.status.Status;
import com.nextcloud.talk.ui.StatusDrawable;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.DisplayUtils;
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
import java.util.List;
import java.util.regex.Pattern;
@ -72,23 +71,23 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
private static final float STATUS_SIZE_IN_DP = 9f;
private final Conversation conversation;
private final UserEntity userEntity;
private final User user;
private final Context context;
private GenericTextHeaderItem header;
private final Status status;
public ConversationItem(Conversation conversation, UserEntity userEntity, Context activityContext, Status status) {
public ConversationItem(Conversation conversation, User user, Context activityContext, Status status) {
this.conversation = conversation;
this.userEntity = userEntity;
this.user = user;
this.context = activityContext;
this.status = status;
}
public ConversationItem(Conversation conversation, UserEntity userEntity,
public ConversationItem(Conversation conversation, User user,
Context activityContext, GenericTextHeaderItem genericTextHeaderItem, Status status) {
this.conversation = conversation;
this.userEntity = userEntity;
this.user = user;
this.context = activityContext;
this.header = genericTextHeaderItem;
this.status = status;
@ -177,7 +176,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.colorPrimary);
holder.binding.dialogUnreadBubble.setTextColor(Color.WHITE);
} else if (conversation.getUnreadMention()) {
if (CapabilitiesUtil.hasSpreedFeatureCapability(userEntity, "direct-mention-flag")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "direct-mention-flag")) {
if (conversation.getUnreadMentionDirect()) {
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.colorPrimary);
holder.binding.dialogUnreadBubble.setTextColor(Color.WHITE);
@ -233,10 +232,10 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
holder.binding.dialogLastMessage.setText(conversation.getLastMessage().getText());
} else {
String authorDisplayName = "";
conversation.getLastMessage().setActiveUser(userEntity);
conversation.getLastMessage().setActiveUser(user);
String text;
if (conversation.getLastMessage().getCalculateMessageType() == ChatMessage.MessageType.REGULAR_TEXT_MESSAGE) {
if (conversation.getLastMessage().getActorId().equals(userEntity.getUserId())) {
if (conversation.getLastMessage().getActorId().equals(user.getUserId())) {
text = String.format(appContext.getString(R.string.nc_formatted_message_you),
conversation.getLastMessage().getLastMessageDisplayText());
} else {
@ -305,10 +304,10 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
.setOldController(holder.binding.dialogAvatar.getController())
.setAutoPlayAnimations(true)
.setImageRequest(DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForAvatar(userEntity.getBaseUrl(),
ApiUtils.getUrlForAvatar(user.getBaseUrl(),
conversation.getName(),
false),
userEntity))
user))
.build();
holder.binding.dialogAvatar.setController(draweeController);
} else {

View file

@ -175,7 +175,7 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setOldController(holder.binding.avatarDraweeView.getController())
.setAutoPlayAnimations(true)
.setImageRequest(DisplayUtils.getImageRequestForUrl(avatarUrl, null))
.setImageRequest(DisplayUtils.getImageRequestForUrl(avatarUrl))
.build();
holder.binding.avatarDraweeView.setController(draweeController);
}

View file

@ -27,8 +27,8 @@ import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.R
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.RvItemSearchMessageBinding
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.domain.SearchMessageEntry
import com.nextcloud.talk.utils.DisplayUtils
import eu.davidea.flexibleadapter.FlexibleAdapter
@ -40,7 +40,7 @@ import eu.davidea.viewholders.FlexibleViewHolder
data class MessageResultItem constructor(
private val context: Context,
private val currentUser: UserEntity,
private val currentUser: User,
val messageEntry: SearchMessageEntry,
private val showHeader: Boolean = false
) :

View file

@ -34,8 +34,8 @@ import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.nextcloud.talk.R;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.databinding.RvItemConversationInfoParticipantBinding;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter;
import com.nextcloud.talk.models.json.participants.Participant;
import com.nextcloud.talk.models.json.participants.Participant.InCallFlags;
@ -63,15 +63,15 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
private final Context context;
private final Participant participant;
private final UserEntity userEntity;
private final User user;
public boolean isOnline = true;
public ParticipantItem(Context activityContext,
Participant participant,
UserEntity userEntity) {
User user) {
this.context = activityContext;
this.participant = participant;
this.userEntity = userEntity;
this.user = user;
}
public Participant getModel() {
@ -168,8 +168,8 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
.setOldController(holder.binding.avatarDraweeView.getController())
.setAutoPlayAnimations(true)
.setImageRequest(DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForGuestAvatar(userEntity.getBaseUrl(),
displayName, false), null))
ApiUtils.getUrlForGuestAvatar(user.getBaseUrl(),
displayName, false)))
.build();
holder.binding.avatarDraweeView.setController(draweeController);
@ -179,8 +179,8 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
.setOldController(holder.binding.avatarDraweeView.getController())
.setAutoPlayAnimations(true)
.setImageRequest(DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForAvatar(userEntity.getBaseUrl(),
participant.getCalculatedActorId(), false), null))
ApiUtils.getUrlForAvatar(user.getBaseUrl(),
participant.getCalculatedActorId(), false)))
.build();
holder.binding.avatarDraweeView.setController(draweeController);
}

View file

@ -46,8 +46,8 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.components.filebrowser.models.BrowserFile;
import com.nextcloud.talk.components.filebrowser.models.DavResponse;
import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.chat.ChatMessage;
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet;
import com.nextcloud.talk.utils.DisplayUtils;
@ -288,7 +288,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
popupMenu.show();
}
private void fetchFileInformation(String url, UserEntity activeUser) {
private void fetchFileInformation(String url, User activeUser) {
Single.fromCallable(new Callable<ReadFilesystemOperation>() {
@Override
public ReadFilesystemOperation call() {

View file

@ -29,7 +29,7 @@ import android.widget.EditText;
import com.facebook.widget.text.span.BetterImageSpan;
import com.nextcloud.talk.R;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.models.json.mention.Mention;
import com.nextcloud.talk.utils.DisplayUtils;
import com.nextcloud.talk.utils.MagicCharPolicy;
@ -40,10 +40,10 @@ import com.vanniktech.emoji.Emojis;
public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
private Context context;
private UserEntity conversationUser;
private User conversationUser;
private EditText editText;
public MentionAutocompleteCallback(Context context, UserEntity conversationUser,
public MentionAutocompleteCallback(Context context, User conversationUser,
EditText editText) {
this.context = context;
this.conversationUser = conversationUser;
@ -53,25 +53,31 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
@Override
public boolean onPopupItemClicked(Editable editable, Mention item) {
int[] range = MagicCharPolicy.getQueryRange(editable);
if (range == null) return false;
if (range == null) {
return false;
}
int start = range[0];
int end = range[1];
String replacement = item.getLabel();
StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
for(EmojiRange emojiRange : Emojis.emojis(replacement)) {
for (EmojiRange emojiRange : Emojis.emojis(replacement)) {
replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
}
editable.replace(start, end, replacementStringBuilder.toString() + " ");
Spans.MentionChipSpan mentionChipSpan =
new Spans.MentionChipSpan(DisplayUtils.getDrawableForMentionChipSpan(context,
item.getId(), item.getLabel(), conversationUser, item.getSource(),
R.xml.chip_you, editText),
BetterImageSpan.ALIGN_CENTER,
item.getId(), item.getLabel());
new Spans.MentionChipSpan(DisplayUtils.getDrawableForMentionChipSpan(context,
item.getId(),
item.getLabel(),
conversationUser,
item.getSource(),
R.xml.chip_you,
editText),
BetterImageSpan.ALIGN_CENTER,
item.getId(), item.getLabel());
editable.setSpan(mentionChipSpan, start, start + replacementStringBuilder.toString().length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
return true;
}

View file

@ -25,7 +25,7 @@ import android.util.Log;
import com.nextcloud.talk.components.filebrowser.models.BrowserFile;
import com.nextcloud.talk.components.filebrowser.models.DavResponse;
import com.nextcloud.talk.dagger.modules.RestModule;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.utils.ApiUtils;
import java.io.IOException;
@ -47,7 +47,7 @@ public class ReadFilesystemOperation {
private final int depth;
private final String basePath;
public ReadFilesystemOperation(OkHttpClient okHttpClient, UserEntity currentUser, String path, int depth) {
public ReadFilesystemOperation(OkHttpClient okHttpClient, User currentUser, String path, int depth) {
OkHttpClient.Builder okHttpClientBuilder = okHttpClient.newBuilder();
okHttpClientBuilder.followRedirects(false);
okHttpClientBuilder.followSslRedirects(false);

View file

@ -122,6 +122,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.callbacks.MentionAutocompleteCallback
import com.nextcloud.talk.controllers.base.NewBaseController
import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerChatBinding
import com.nextcloud.talk.events.UserMentionClickEvent
import com.nextcloud.talk.events.WebSocketCommunicationEvent
@ -129,8 +130,6 @@ import com.nextcloud.talk.jobs.DownloadFileToCacheWorker
import com.nextcloud.talk.jobs.ShareOperationWorker
import com.nextcloud.talk.jobs.UploadAndShareFilesWorker
import com.nextcloud.talk.messagesearch.MessageSearchActivity
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.chat.ChatOverall
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
@ -168,6 +167,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
import com.nextcloud.talk.utils.rx.DisposableSet
@ -239,7 +239,7 @@ class ChatController(args: Bundle) :
val disposables = DisposableSet()
var roomToken: String? = null
val conversationUser: UserEntity?
val conversationUser: User?
val roomPassword: String
var credentials: String? = null
var currentConversation: Conversation? = null
@ -322,7 +322,7 @@ class ChatController(args: Bundle) :
}
private fun getRoomInfo() {
val shouldRepeat = CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "webinary-lobby")
val shouldRepeat = CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "webinary-lobby")
if (shouldRepeat) {
checkingLobbyStatus = true
}
@ -656,7 +656,7 @@ class ChatController(args: Bundle) :
})
val filters = arrayOfNulls<InputFilter>(1)
val lengthFilter = CapabilitiesUtil.getMessageMaxLength(conversationUser) ?: MESSAGE_MAX_LENGTH
val lengthFilter = CapabilitiesUtilNew.getMessageMaxLength(conversationUser) ?: MESSAGE_MAX_LENGTH
filters[0] = InputFilter.LengthFilter(lengthFilter)
binding.messageInputView.inputEditText?.filters = filters
@ -844,7 +844,7 @@ class ChatController(args: Bundle) :
binding.messageInputView.button.setOnClickListener { submitMessage(false) }
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "silent-send")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-send")) {
binding.messageInputView.button.setOnLongClickListener {
showSendButtonMenu()
true
@ -1016,7 +1016,7 @@ class ChatController(args: Bundle) :
val baseUrl = message.activeUser!!.baseUrl
val userId = message.activeUser!!.userId
val attachmentFolder = CapabilitiesUtil.getAttachmentFolder(message.activeUser)
val attachmentFolder = CapabilitiesUtilNew.getAttachmentFolder(message.activeUser!!)
val fileName = message.selectedIndividualHashMap!!["name"]
var size = message.selectedIndividualHashMap!!["size"]
if (size == null) {
@ -1254,7 +1254,7 @@ class ChatController(args: Bundle) :
}
private fun disableCallButtons() {
if (CapabilitiesUtil.isAbleToCall(conversationUser)) {
if (CapabilitiesUtilNew.isAbleToCall(conversationUser)) {
if (conversationVoiceCallMenuItem != null && conversationVideoMenuItem != null) {
conversationVoiceCallMenuItem?.icon?.alpha = SEMI_TRANSPARENT_INT
conversationVideoMenuItem?.icon?.alpha = SEMI_TRANSPARENT_INT
@ -1267,7 +1267,7 @@ class ChatController(args: Bundle) :
}
private fun enableCallButtons() {
if (CapabilitiesUtil.isAbleToCall(conversationUser)) {
if (CapabilitiesUtilNew.isAbleToCall(conversationUser)) {
if (conversationVoiceCallMenuItem != null && conversationVideoMenuItem != null) {
conversationVoiceCallMenuItem?.icon?.alpha = FULLY_OPAQUE_INT
conversationVideoMenuItem?.icon?.alpha = FULLY_OPAQUE_INT
@ -1351,10 +1351,10 @@ class ChatController(args: Bundle) :
val pathList = intent?.getStringArrayListExtra(RemoteFileBrowserActivity.EXTRA_SELECTED_PATHS)
if (pathList?.size!! >= 1) {
pathList
.chunked(10)
.chunked(CHUNK_SIZE)
.forEach { paths ->
val data = Data.Builder()
.putLong(KEY_INTERNAL_USER_ID, conversationUser!!.id)
.putLong(KEY_INTERNAL_USER_ID, conversationUser!!.id!!)
.putString(KEY_ROOM_TOKEN, roomToken)
.putStringArray(KEY_FILE_PATHS, paths.toTypedArray())
.build()
@ -1576,7 +1576,7 @@ class ChatController(args: Bundle) :
.putStringArray(UploadAndShareFilesWorker.DEVICE_SOURCEFILES, files.toTypedArray())
.putString(
UploadAndShareFilesWorker.NC_TARGETPATH,
CapabilitiesUtil.getAttachmentFolder(conversationUser)
CapabilitiesUtilNew.getAttachmentFolder(conversationUser!!)
)
.putString(UploadAndShareFilesWorker.ROOM_TOKEN, roomToken)
.putString(UploadAndShareFilesWorker.META_DATA, metaData)
@ -1656,7 +1656,7 @@ class ChatController(args: Bundle) :
val presenter = MentionAutocompletePresenter(activity, roomToken)
val callback = MentionAutocompleteCallback(
activity,
conversationUser,
conversationUser!!,
binding.messageInputView.inputEditText
)
@ -1690,7 +1690,7 @@ class ChatController(args: Bundle) :
eventBus?.register(this)
if (conversationUser?.userId != "?" &&
CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "mention-flag") ?: false &&
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag") ?: false &&
activity != null
) {
activity?.findViewById<View>(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() }
@ -1845,7 +1845,7 @@ class ChatController(args: Bundle) :
var apiVersion = 1
// FIXME Fix API checking with guests?
if (conversationUser != null) {
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
apiVersion = ApiUtils.getConversationApiVersion(conversationUser!!, intArrayOf(ApiUtils.APIv4, 1))
}
val startNanoTime = System.nanoTime()
@ -2076,9 +2076,9 @@ class ChatController(args: Bundle) :
private fun setupWebsocket() {
if (conversationUser != null) {
if (WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id) != null) {
if (WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id!!) != null) {
magicWebSocketInstance =
WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id)
WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id!!)
} else {
Log.d(TAG, "magicWebSocketInstance became null")
magicWebSocketInstance = null
@ -2468,7 +2468,7 @@ class ChatController(args: Bundle) :
} else {
conversationInfoMenuItem = menu.findItem(R.id.conversation_info)
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
conversationSharedItemsItem = menu.findItem(R.id.shared_items)
} else {
menu.removeItem(R.id.shared_items)
@ -2477,11 +2477,11 @@ class ChatController(args: Bundle) :
loadAvatarForStatusBar()
}
if (CapabilitiesUtil.isAbleToCall(conversationUser)) {
if (CapabilitiesUtilNew.isAbleToCall(conversationUser)) {
conversationVoiceCallMenuItem = menu.findItem(R.id.conversation_voice_call)
conversationVideoMenuItem = menu.findItem(R.id.conversation_video_call)
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "silent-call")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-call")) {
Handler().post {
activity?.findViewById<View?>(R.id.conversation_voice_call)?.setOnLongClickListener {
showCallButtonMenu(true)
@ -2505,11 +2505,11 @@ class ChatController(args: Bundle) :
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
conversationUser?.let {
if (CapabilitiesUtil.hasSpreedFeatureCapability(it, "read-only-rooms")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(it, "read-only-rooms")) {
checkShowCallButtons()
}
val searchItem = menu.findItem(R.id.conversation_search)
searchItem.isVisible = CapabilitiesUtil.isUnifiedSearchAvailable(it)
searchItem.isVisible = CapabilitiesUtilNew.isUnifiedSearchAvailable(it)
}
}
@ -2791,7 +2791,7 @@ class ChatController(args: Bundle) :
Parcels.wrap(roomOverall.ocs!!.data!!)
)
remapChatController(
router, conversationUser!!.id,
router, conversationUser!!.id!!,
roomOverall.ocs!!.data!!.token!!, bundle, true
)
}
@ -2942,7 +2942,7 @@ class ChatController(args: Bundle) :
}
private fun showMicrophoneButton(show: Boolean) {
if (show && CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) {
if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) {
binding.messageInputView.messageSendButton.visibility = View.GONE
binding.messageInputView.recordAudioButton.visibility = View.VISIBLE
} else {
@ -3010,7 +3010,7 @@ class ChatController(args: Bundle) :
message.isDeleted -> false
message.hasFileAttachment() -> false
OBJECT_MESSAGE == message.message -> false
!CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "delete-messages") -> false
!CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "delete-messages") -> false
!hasChatPermission -> false
else -> true
}
@ -3093,7 +3093,7 @@ class ChatController(args: Bundle) :
conversationIntent.putExtras(bundle)
ConductorRemapping.remapChatController(
router, conversationUser.id,
router, conversationUser.id!!,
roomOverall.ocs!!.data!!.token!!, bundle, false
)
} else {
@ -3173,5 +3173,6 @@ class ChatController(args: Bundle) :
private const val ANIMATION_DURATION: Long = 750
private const val RETRIES: Long = 3
private const val LOOKING_INTO_FUTURE_TIMEOUT = 30
private const val CHUNK_SIZE: Int = 10
}
}

View file

@ -51,7 +51,6 @@ import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.facebook.drawee.backends.pipeline.Fresco
import com.nextcloud.talk.R
import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
import com.nextcloud.talk.adapters.items.ParticipantItem
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
@ -59,12 +58,11 @@ import com.nextcloud.talk.controllers.base.NewBaseController
import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage
import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage
import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerConversationInfoBinding
import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.jobs.DeleteConversationWorker
import com.nextcloud.talk.jobs.LeaveConversationWorker
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
@ -74,11 +72,13 @@ import com.nextcloud.talk.models.json.participants.Participant.ActorType.CIRCLES
import com.nextcloud.talk.models.json.participants.Participant.ActorType.GROUPS
import com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS
import com.nextcloud.talk.models.json.participants.ParticipantsOverall
import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DateConstants
import com.nextcloud.talk.utils.DateUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule
import com.yarolegovich.lovelydialog.LovelySaveStateHandler
import com.yarolegovich.lovelydialog.LovelyStandardDialog
@ -115,7 +115,7 @@ class ConversationInfoController(args: Bundle) :
var eventBus: EventBus? = null
private val conversationToken: String?
private val conversationUser: UserEntity?
private val conversationUser: User?
private val hasAvatarSpacing: Boolean
private val credentials: String?
private var roomDisposable: Disposable? = null
@ -134,7 +134,7 @@ class ConversationInfoController(args: Bundle) :
if (!TextUtils.isEmpty(conversationToken) && conversationUser != null) {
val data = Data.Builder()
data.putString(BundleKeys.KEY_ROOM_TOKEN, conversationToken)
data.putLong(BundleKeys.KEY_INTERNAL_USER_ID, conversationUser.id)
data.putLong(BundleKeys.KEY_INTERNAL_USER_ID, conversationUser.id!!)
return data.build()
}
@ -176,7 +176,7 @@ class ConversationInfoController(args: Bundle) :
binding.clearConversationHistory.setOnClickListener { showClearHistoryDialog(null) }
binding.addParticipantsAction.setOnClickListener { addParticipants() }
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
binding.showSharedItemsAction.setOnClickListener { showSharedItems() }
} else {
binding.categorySharedItems.visibility = View.GONE
@ -206,7 +206,7 @@ class ConversationInfoController(args: Bundle) :
}
private fun setupWebinaryView() {
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "webinary-lobby") &&
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "webinary-lobby") &&
webinaryRoomType(conversation!!) &&
conversation!!.canModerate(conversationUser!!)
) {
@ -624,7 +624,7 @@ class ConversationInfoController(args: Bundle) :
if (conversationCopy!!.canModerate(conversationUser)) {
binding.addParticipantsAction.visibility = View.VISIBLE
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "clear-history")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "clear-history")) {
binding.clearConversationHistory.visibility = View.VISIBLE
} else {
binding.clearConversationHistory.visibility = View.GONE
@ -701,7 +701,7 @@ class ConversationInfoController(args: Bundle) :
if (conversation != null) {
if (
conversationUser != null &&
CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "notification-levels")
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")
) {
binding.notificationSettingsView.conversationInfoMessageNotifications.isEnabled = true
binding.notificationSettingsView.conversationInfoMessageNotifications.alpha = 1.0f
@ -730,7 +730,7 @@ class ConversationInfoController(args: Bundle) :
private fun setProperNotificationValue(conversation: Conversation?) {
if (conversation!!.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
// hack to see if we get mentioned always or just on mention
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "mention-flag")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag")) {
binding.notificationSettingsView.conversationInfoMessageNotifications.value = "always"
} else {
binding.notificationSettingsView.conversationInfoMessageNotifications.value = "mention"

View file

@ -74,6 +74,7 @@ import com.nextcloud.talk.adapters.items.MessagesTextHeaderItem;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.controllers.base.BaseController;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.events.ConversationsListFetchDataEvent;
import com.nextcloud.talk.events.EventStatus;
import com.nextcloud.talk.interfaces.ConversationMenuInterface;
@ -82,8 +83,6 @@ import com.nextcloud.talk.jobs.ContactAddressBookWorker;
import com.nextcloud.talk.jobs.DeleteConversationWorker;
import com.nextcloud.talk.jobs.UploadAndShareFilesWorker;
import com.nextcloud.talk.messagesearch.MessageSearchHelper;
import com.nextcloud.talk.models.database.CapabilitiesUtil;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.domain.SearchMessageEntry;
import com.nextcloud.talk.models.json.conversations.Conversation;
import com.nextcloud.talk.models.json.status.Status;
@ -91,6 +90,7 @@ import com.nextcloud.talk.models.json.statuses.StatusesOverall;
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository;
import com.nextcloud.talk.ui.dialog.ChooseAccountDialogFragment;
import com.nextcloud.talk.ui.dialog.ConversationsListBottomDialog;
import com.nextcloud.talk.users.UserManager;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.AttendeePermissionsUtil;
import com.nextcloud.talk.utils.ClosedInterfaceImpl;
@ -98,7 +98,7 @@ import com.nextcloud.talk.utils.ConductorRemapping;
import com.nextcloud.talk.utils.DisplayUtils;
import com.nextcloud.talk.utils.UriUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
import com.nextcloud.talk.utils.preferences.AppPreferences;
import com.nextcloud.talk.utils.rx.SearchViewObservable;
import com.webianks.library.PopupBubble;
@ -162,7 +162,7 @@ public class ConversationsListController extends BaseController implements Flexi
private final Bundle bundle;
@Inject
UserUtils userUtils;
UserManager userManager;
@Inject
EventBus eventBus;
@ -197,7 +197,7 @@ public class ConversationsListController extends BaseController implements Flexi
@BindView(R.id.newMentionPopupBubble)
PopupBubble newMentionPopupBubble;
private UserEntity currentUser;
private User currentUser;
private Disposable roomsQueryDisposable;
private Disposable openConversationsQueryDisposable;
private FlexibleAdapter<AbstractFlexibleItem> adapter;
@ -320,15 +320,15 @@ public class ConversationsListController extends BaseController implements Flexi
if (!eventBus.isRegistered(this)) {
eventBus.register(this);
}
currentUser = userUtils.getCurrentUser();
currentUser = userManager.getCurrentUser().blockingGet();
if (currentUser != null) {
if (CapabilitiesUtil.isServerEOL(currentUser)) {
if (CapabilitiesUtilNew.isServerEOL(currentUser)) {
showServerEOLDialog();
return;
}
if (CapabilitiesUtil.isUnifiedSearchAvailable(currentUser)) {
if (CapabilitiesUtilNew.isUnifiedSearchAvailable(currentUser)) {
searchHelper = new MessageSearchHelper(unifiedSearchRepository);
}
@ -518,7 +518,7 @@ public class ConversationsListController extends BaseController implements Flexi
@SuppressLint("LongLogTag")
public void fetchData() {
if (CapabilitiesUtil.isUserStatusAvailable(userUtils.getCurrentUser())) {
if (CapabilitiesUtilNew.isUserStatusAvailable(userManager.getCurrentUser().blockingGet())) {
fetchUserStatusesAndRooms();
} else {
fetchRooms();
@ -682,7 +682,7 @@ public class ConversationsListController extends BaseController implements Flexi
searchableConversationItems.clear();
searchableConversationItems.addAll(conversationItemsWithHeader);
if (CapabilitiesUtil.hasSpreedFeatureCapability(currentUser, "listable-rooms")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "listable-rooms")) {
List<AbstractFlexibleItem> openConversationItems = new ArrayList<>();
openConversationsQueryDisposable = ncApi.getOpenConversations(
@ -904,7 +904,7 @@ public class ConversationsListController extends BaseController implements Flexi
clearMessageSearchResults();
adapter.setFilter(filter);
adapter.filterItems();
if (CapabilitiesUtil.isUnifiedSearchAvailable(currentUser)) {
if (CapabilitiesUtilNew.isUnifiedSearchAvailable(currentUser)) {
startMessageSearch(filter);
}
} else {
@ -1088,7 +1088,7 @@ public class ConversationsListController extends BaseController implements Flexi
conversationsListBottomDialog = new ConversationsListBottomDialog(
getActivity(),
this,
userUtils.getCurrentUser(),
userManager.getCurrentUser().blockingGet(),
conversation);
conversationsListBottomDialog.show();
}
@ -1156,7 +1156,7 @@ public class ConversationsListController extends BaseController implements Flexi
.putStringArray(UploadAndShareFilesWorker.DEVICE_SOURCEFILES, filesToShareArray)
.putString(
UploadAndShareFilesWorker.NC_TARGETPATH,
CapabilitiesUtil.getAttachmentFolder(currentUser))
CapabilitiesUtilNew.getAttachmentFolder(currentUser))
.putString(UploadAndShareFilesWorker.ROOM_TOKEN, selectedConversation.getToken())
.build();
OneTimeWorkRequest uploadWorker = new OneTimeWorkRequest.Builder(UploadAndShareFilesWorker.class)
@ -1285,7 +1285,9 @@ public class ConversationsListController extends BaseController implements Flexi
.setPositiveButton(R.string.nc_delete, new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId());
boolean otherUserExists = userManager
.scheduleUserForDeletionWithId(currentUser.getId())
.blockingGet();
OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build();
WorkManager.getInstance().enqueue(accountRemovalWork);
@ -1328,7 +1330,9 @@ public class ConversationsListController extends BaseController implements Flexi
.setPositiveButton(R.string.nc_settings_remove_account, new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId());
boolean otherUserExists = userManager
.scheduleUserForDeletionWithId(currentUser.getId())
.blockingGet();
OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build();
WorkManager.getInstance().enqueue(accountRemovalWork);
@ -1347,7 +1351,7 @@ public class ConversationsListController extends BaseController implements Flexi
.setNegativeButton(R.string.nc_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
if (userUtils.hasMultipleUsers()) {
if (userManager.getUsers().blockingGet().size() > 0) {
getRouter().pushController(RouterTransaction.with(new SwitchAccountController()));
} else {
getActivity().finishAffinity();

View file

@ -45,10 +45,10 @@ import com.nextcloud.talk.controllers.base.NewBaseController
import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.databinding.ControllerEntryMenuBinding
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ShareUtils
import com.nextcloud.talk.utils.UriUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
import com.vanniktech.emoji.EmojiPopup
import okhttp3.internal.immutableListOf
@ -65,13 +65,11 @@ class EntryMenuController(args: Bundle) :
) {
private val binding: ControllerEntryMenuBinding by viewBinding(ControllerEntryMenuBinding::bind)
@JvmField
@Inject
var eventBus: EventBus? = null
lateinit var eventBus: EventBus
@JvmField
@Inject
var userUtils: UserUtils? = null
lateinit var userManager: UserManager
private val operation: ConversationOperationEnum
private var conversation: Conversation? = null
@ -271,7 +269,7 @@ class EntryMenuController(args: Bundle) :
ShareUtils.getStringForIntent(
activity,
binding.textEdit.text.toString(),
userUtils,
userManager,
conversation
)
)

View file

@ -39,11 +39,11 @@ import com.nextcloud.talk.adapters.items.LoadMoreResultsItem
import com.nextcloud.talk.adapters.items.MessageResultItem
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.controllers.ConversationsListController
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivityMessageSearchBinding
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CurrentUserProvider
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import com.nextcloud.talk.utils.rx.SearchViewObservable.Companion.observeSearchView
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
@ -62,12 +62,12 @@ class MessageSearchActivity : BaseActivity() {
lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject
lateinit var userProvider: CurrentUserProvider
lateinit var userProvider: CurrentUserProviderNew
private lateinit var binding: ActivityMessageSearchBinding
private lateinit var searchView: SearchView
private lateinit var user: UserEntity
private lateinit var user: User
private lateinit var viewModel: MessageSearchViewModel
@ -84,7 +84,7 @@ class MessageSearchActivity : BaseActivity() {
setContentView(binding.root)
viewModel = ViewModelProvider(this, viewModelFactory)[MessageSearchViewModel::class.java]
user = userProvider.currentUser!!
user = userProvider.currentUser.blockingGet()
val roomToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!!
viewModel.initialize(roomToken)
setupStateObserver()

View file

@ -33,7 +33,7 @@ import com.bluelinelabs.logansquare.annotation.JsonIgnore
import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.chat.ChatUtils.Companion.getParsedMessage
import com.nextcloud.talk.models.json.converters.EnumSystemMessageTypeConverter
import com.nextcloud.talk.utils.ApiUtils
@ -41,11 +41,8 @@ import com.stfalcon.chatkit.commons.models.IUser
import com.stfalcon.chatkit.commons.models.MessageContentType
import kotlinx.android.parcel.Parcelize
import java.security.MessageDigest
import java.util.ArrayList
import java.util.Arrays
import java.util.Date
import java.util.HashMap
import java.util.LinkedHashMap
@Parcelize
@JsonObject
@ -57,7 +54,7 @@ data class ChatMessage(
var isOneToOneConversation: Boolean = false,
@JsonIgnore
var activeUser: UserEntity? = null,
var activeUser: User? = null,
@JsonIgnore
var selectedIndividualHashMap: Map<String?, String?>? = null,

View file

@ -26,8 +26,7 @@ package com.nextcloud.talk.models.json.conversations
import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField
import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.converters.EnumLobbyStateConverter
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
@ -35,6 +34,7 @@ import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter
import com.nextcloud.talk.models.json.converters.EnumReadOnlyConversationConverter
import com.nextcloud.talk.models.json.converters.EnumRoomTypeConverter
import com.nextcloud.talk.models.json.participants.Participant.ParticipantType
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import kotlinx.android.parcel.Parcelize
@Parcelize
@ -140,25 +140,25 @@ data class Conversation(
ParticipantType.GUEST_MODERATOR == participantType ||
ParticipantType.MODERATOR == participantType
private fun isLockedOneToOne(conversationUser: UserEntity): Boolean {
private fun isLockedOneToOne(conversationUser: User): Boolean {
return type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
}
fun canModerate(conversationUser: UserEntity): Boolean {
fun canModerate(conversationUser: User): Boolean {
return isParticipantOwnerOrModerator && !isLockedOneToOne(conversationUser)
}
fun shouldShowLobby(conversationUser: UserEntity): Boolean {
fun shouldShowLobby(conversationUser: User): Boolean {
return LobbyState.LOBBY_STATE_MODERATORS_ONLY == lobbyState && !canModerate(conversationUser)
}
fun isLobbyViewApplicable(conversationUser: UserEntity): Boolean {
fun isLobbyViewApplicable(conversationUser: User): Boolean {
return !canModerate(conversationUser) &&
(type == ConversationType.ROOM_GROUP_CALL || type == ConversationType.ROOM_PUBLIC_CALL)
}
fun isNameEditable(conversationUser: UserEntity): Boolean {
fun isNameEditable(conversationUser: User): Boolean {
return canModerate(conversationUser) && ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != type
}
@ -171,7 +171,7 @@ data class Conversation(
}
}
fun canDelete(conversationUser: UserEntity): Boolean {
fun canDelete(conversationUser: User): Boolean {
return if (canDeleteConversation != null) {
// Available since APIv2
canDeleteConversation!!

View file

@ -113,7 +113,7 @@ class RemoteFileBrowserItemsListViewHolder(
if (path.isNotEmpty()) {
val draweeController: DraweeController = Fresco.newDraweeControllerBuilder()
.setAutoPlayAnimations(true)
.setImageRequest(DisplayUtils.getImageRequestForUrl(path, null))
.setImageRequest(DisplayUtils.getImageRequestForUrl(path))
.build()
binding.fileIcon.controller = draweeController
}

View file

@ -36,8 +36,8 @@ import autodagger.AutoInjector
import com.google.android.material.tabs.TabLayout
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivitySharedItemsBinding
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.shareditems.adapters.SharedItemsAdapter
import com.nextcloud.talk.shareditems.model.SharedItemType
import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel
@ -62,7 +62,7 @@ class SharedItemsActivity : AppCompatActivity() {
val roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!!
val conversationName = intent.getStringExtra(KEY_CONVERSATION_NAME)
val userEntity = intent.getParcelableExtra<UserEntity>(KEY_USER_ENTITY)!!
val user = intent.getParcelableExtra<User>(KEY_USER_ENTITY)!!
binding = ActivitySharedItemsBinding.inflate(layoutInflater)
setSupportActionBar(binding.sharedItemsToolbar)
@ -104,7 +104,7 @@ class SharedItemsActivity : AppCompatActivity() {
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
}
val adapter = SharedItemsAdapter(showGrid, userEntity).apply {
val adapter = SharedItemsAdapter(showGrid, user).apply {
items = sharedMediaItems.items
}
binding.imageRecycler.adapter = adapter
@ -125,7 +125,7 @@ class SharedItemsActivity : AppCompatActivity() {
}
})
viewModel.initialize(userEntity, roomToken)
viewModel.initialize(user, roomToken)
}
private fun clearEmptyLoading() {

View file

@ -25,14 +25,14 @@ package com.nextcloud.talk.shareditems.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.SharedItemGridBinding
import com.nextcloud.talk.databinding.SharedItemListBinding
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.shareditems.model.SharedItem
class SharedItemsAdapter(
private val showGrid: Boolean,
private val userEntity: UserEntity
private val user: User
) : RecyclerView.Adapter<SharedItemsViewHolder>() {
var items: List<SharedItem> = emptyList()
@ -46,7 +46,7 @@ class SharedItemsAdapter(
parent,
false
),
userEntity
user
)
} else {
SharedItemsListViewHolder(
@ -55,7 +55,7 @@ class SharedItemsAdapter(
parent,
false
),
userEntity
user
)
}
}

View file

@ -25,13 +25,13 @@ package com.nextcloud.talk.shareditems.adapters
import android.view.View
import android.widget.ProgressBar
import com.facebook.drawee.view.SimpleDraweeView
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.SharedItemGridBinding
import com.nextcloud.talk.models.database.UserEntity
class SharedItemsGridViewHolder(
override val binding: SharedItemGridBinding,
userEntity: UserEntity
) : SharedItemsViewHolder(binding, userEntity) {
user: User
) : SharedItemsViewHolder(binding, user) {
override val image: SimpleDraweeView
get() = binding.image

View file

@ -26,15 +26,15 @@ import android.text.format.Formatter
import android.view.View
import android.widget.ProgressBar
import com.facebook.drawee.view.SimpleDraweeView
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.SharedItemListBinding
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.shareditems.model.SharedItem
import com.nextcloud.talk.utils.DateUtils
class SharedItemsListViewHolder(
override val binding: SharedItemListBinding,
userEntity: UserEntity
) : SharedItemsViewHolder(binding, userEntity) {
user: User
) : SharedItemsViewHolder(binding, user) {
override val image: SimpleDraweeView
get() = binding.fileImage

View file

@ -38,7 +38,7 @@ import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.common.RotationOptions
import com.facebook.imagepipeline.image.ImageInfo
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.shareditems.model.SharedItem
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DrawableUtils
@ -46,7 +46,7 @@ import com.nextcloud.talk.utils.FileViewerUtils
abstract class SharedItemsViewHolder(
open val binding: ViewBinding,
private val userEntity: UserEntity
private val user: User
) : RecyclerView.ViewHolder(binding.root) {
companion object {
@ -60,7 +60,7 @@ abstract class SharedItemsViewHolder(
private val authHeader = mapOf(
Pair(
"Authorization",
ApiUtils.getCredentials(userEntity.username, userEntity.token)
ApiUtils.getCredentials(user.username, user.token)
)
)
@ -76,7 +76,7 @@ abstract class SharedItemsViewHolder(
This should be done after a refactoring of FileViewerUtils.
*/
val fileViewerUtils = FileViewerUtils(image.context, userEntity)
val fileViewerUtils = FileViewerUtils(image.context, user)
clickTarget.setOnClickListener {
fileViewerUtils.openFile(

View file

@ -26,7 +26,7 @@ import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.shareditems.model.SharedItemType
import com.nextcloud.talk.shareditems.model.SharedMediaItems
import com.nextcloud.talk.shareditems.repositories.SharedItemsRepository
@ -57,11 +57,11 @@ class SharedItemsViewModel @Inject constructor(
val viewState: LiveData<ViewState>
get() = _viewState
fun initialize(userEntity: UserEntity, roomToken: String) {
fun initialize(user: User, roomToken: String) {
repositoryParameters = SharedItemsRepository.Parameters(
userEntity.userId,
userEntity.token,
userEntity.baseUrl,
user.userId!!,
user.token!!,
user.baseUrl!!,
roomToken
)
loadAvailableTypes()

View file

@ -33,7 +33,7 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage
import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.hovercard.HoverCardAction
import com.nextcloud.talk.models.json.hovercard.HoverCardOverall
@ -51,7 +51,7 @@ import org.parceler.Parcels
private const val TAG = "ProfileBottomSheet"
class ProfileBottomSheet(val ncApi: NcApi, val userEntity: UserEntity, val router: Router) {
class ProfileBottomSheet(val ncApi: NcApi, val userEntity: User, val router: Router) {
private val allowedAppIds = listOf(SPREED.stringValue, PROFILE.stringValue, EMAIL.stringValue)
@ -172,7 +172,7 @@ class ProfileBottomSheet(val ncApi: NcApi, val userEntity: UserEntity, val route
Parcels.wrap(roomOverall.ocs!!.data)
)
ConductorRemapping.remapChatController(
router, userEntity.id,
router, userEntity.id!!,
roomOverall.ocs!!.data!!.token!!, bundle, true
)
}

View file

@ -31,7 +31,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.nextcloud.talk.R
import com.nextcloud.talk.controllers.ChatController
import com.nextcloud.talk.databinding.DialogAttachmentBinding
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
class AttachmentDialog(val activity: Activity, var chatController: ChatController) : BottomSheetDialog(activity) {
@ -43,7 +43,7 @@ class AttachmentDialog(val activity: Activity, var chatController: ChatControlle
setContentView(dialogAttachmentBinding.root)
window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
var serverName = CapabilitiesUtil.getServerName(chatController.conversationUser)
var serverName = CapabilitiesUtilNew.getServerName(chatController.conversationUser)
dialogAttachmentBinding.txtAttachFileFromCloud.text = chatController.resources?.let {
if (serverName.isNullOrEmpty()) {
serverName = it.getString(R.string.nc_server_product_name)
@ -51,7 +51,7 @@ class AttachmentDialog(val activity: Activity, var chatController: ChatControlle
String.format(it.getString(R.string.nc_upload_from_cloud), serverName)
}
if (!CapabilitiesUtil.hasSpreedFeatureCapability(
if (!CapabilitiesUtilNew.hasSpreedFeatureCapability(
chatController.conversationUser,
"geo-location-sharing"
)

View file

@ -132,8 +132,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
ApiUtils.getUrlForAvatar(
user.getBaseUrl(),
user.getUserId(),
false),
null))
false)))
.build();
binding.currentAccount.userIcon.setController(draweeController);

View file

@ -42,28 +42,28 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.controllers.ConversationsListController
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_ADD_FAVORITE
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_REMOVE_FAVORITE
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_SET_PASSWORD
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_CLEAR_PASSWORD
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MAKE_PRIVATE
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MAKE_PUBLIC
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_RENAME_ROOM
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MARK_AS_READ
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_REMOVE_FAVORITE
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_RENAME_ROOM
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_SET_PASSWORD
import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController
import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.DialogConversationOperationsBinding
import com.nextcloud.talk.jobs.LeaveConversationWorker
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.Mimetype.TEXT_PLAIN
import com.nextcloud.talk.utils.ShareUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPERATION_CODE
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import org.parceler.Parcels
import javax.inject.Inject
@ -71,7 +71,7 @@ import javax.inject.Inject
class ConversationsListBottomDialog(
val activity: Activity,
val controller: ConversationsListController,
val currentUser: UserEntity,
val currentUser: User,
val conversation: Conversation
) : BottomSheetDialog(activity) {
@ -80,12 +80,10 @@ class ConversationsListBottomDialog(
private lateinit var binding: DialogConversationOperationsBinding
@Inject
@JvmField
var ncApi: NcApi? = null
lateinit var ncApi: NcApi
@Inject
@JvmField
var userUtils: UserUtils? = null
lateinit var userManager: UserManager
init {
NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
@ -111,7 +109,7 @@ class ConversationsListBottomDialog(
}
private fun initItemsVisibility() {
val hasFavoritesCapability = CapabilitiesUtil.hasSpreedFeatureCapability(currentUser, "favorites")
val hasFavoritesCapability = CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "favorites")
val canModerate = conversation.canModerate(currentUser)
binding.conversationOperationRemoveFavorite.visibility = setVisibleIf(
@ -122,7 +120,7 @@ class ConversationsListBottomDialog(
)
binding.conversationOperationMarkAsRead.visibility = setVisibleIf(
conversation.unreadMessages > 0 && CapabilitiesUtil.canSetChatReadMarker(currentUser)
conversation.unreadMessages > 0 && CapabilitiesUtilNew.canSetChatReadMarker(currentUser)
)
binding.conversationOperationRename.visibility = setVisibleIf(
@ -185,7 +183,7 @@ class ConversationsListBottomDialog(
binding.conversationOperationLeave.setOnClickListener {
val dataBuilder = Data.Builder()
dataBuilder.putString(KEY_ROOM_TOKEN, conversation.token)
dataBuilder.putLong(KEY_INTERNAL_USER_ID, currentUser.id)
dataBuilder.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!)
val data = dataBuilder.build()
val leaveConversationWorker =
@ -200,7 +198,7 @@ class ConversationsListBottomDialog(
binding.conversationOperationDelete.setOnClickListener {
if (!TextUtils.isEmpty(conversation.token)) {
val bundle = Bundle()
bundle.putLong(KEY_INTERNAL_USER_ID, currentUser.id)
bundle.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!)
bundle.putParcelable(KEY_ROOM, Parcels.wrap(conversation))
controller.openLovelyDialogWithIdAndBundle(
@ -254,7 +252,7 @@ class ConversationsListBottomDialog(
// password should not be shared!!
putExtra(
Intent.EXTRA_TEXT,
ShareUtils.getStringForIntent(activity, null, userUtils, conversation)
ShareUtils.getStringForIntent(activity, null, userManager, conversation)
)
}

View file

@ -38,13 +38,13 @@ import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.controllers.ChatController
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.DialogMessageActionsBinding
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.vanniktech.emoji.EmojiPopup
import com.vanniktech.emoji.EmojiTextView
import com.vanniktech.emoji.installDisableKeyboardInput
@ -57,7 +57,7 @@ import io.reactivex.schedulers.Schedulers
class MessageActionsDialog(
private val chatController: ChatController,
private val message: ChatMessage,
private val user: UserEntity?,
private val user: User?,
private val currentConversation: Conversation?,
private val showMessageDeletionButton: Boolean,
private val hasChatPermission: Boolean,
@ -102,8 +102,8 @@ class MessageActionsDialog(
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
}
private fun hasUserId(user: UserEntity?): Boolean {
return user?.userId?.isNotEmpty() == true && user?.userId != "?"
private fun hasUserId(user: User?): Boolean {
return user?.userId?.isNotEmpty() == true && user.userId != "?"
}
private fun hasUserActorId(message: ChatMessage): Boolean {
@ -165,7 +165,7 @@ class MessageActionsDialog(
}
private fun initEmojiBar(hasChatPermission: Boolean) {
if (CapabilitiesUtil.hasSpreedFeatureCapability(user, "reactions") &&
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "reactions") &&
isPermitted(hasChatPermission) &&
isReactableMessageType(message)
) {

View file

@ -44,9 +44,9 @@ import com.nextcloud.talk.adapters.ReactionItemClickListener
import com.nextcloud.talk.adapters.ReactionsAdapter
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.DialogMessageReactionsBinding
import com.nextcloud.talk.databinding.ItemReactionsTabBinding
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.generic.GenericOverall
@ -57,14 +57,13 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.Collections
import java.util.Comparator
@AutoInjector(NextcloudTalkApplication::class)
class ShowReactionsDialog(
activity: Activity,
private val currentConversation: Conversation?,
private val chatMessage: ChatMessage,
private val userEntity: UserEntity?,
private val user: User?,
private val hasChatPermission: Boolean,
private val ncApi: NcApi
) : BottomSheetDialog(activity), ReactionItemClickListener {
@ -80,7 +79,7 @@ class ShowReactionsDialog(
binding = DialogMessageReactionsBinding.inflate(layoutInflater)
setContentView(binding.root)
window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
adapter = ReactionsAdapter(this, userEntity)
adapter = ReactionsAdapter(this, user)
binding.reactionsList.adapter = adapter
binding.reactionsList.layoutManager = LinearLayoutManager(context)
initEmojiReactions()
@ -145,12 +144,12 @@ class ShowReactionsDialog(
private fun updateParticipantsForEmoji(chatMessage: ChatMessage, emoji: String?) {
adapter?.list?.clear()
val credentials = ApiUtils.getCredentials(userEntity?.username, userEntity?.token)
val credentials = ApiUtils.getCredentials(user?.username, user?.token)
ncApi.getReactions(
credentials,
ApiUtils.getUrlForMessageReaction(
userEntity?.baseUrl,
user?.baseUrl,
currentConversation!!.token,
chatMessage.id
),
@ -173,7 +172,7 @@ class ShowReactionsDialog(
}
}
Collections.sort(reactionVoters, ReactionComparator(userEntity?.userId))
Collections.sort(reactionVoters, ReactionComparator(user?.userId))
adapter?.list?.addAll(reactionVoters)
adapter?.notifyDataSetChanged()
@ -193,19 +192,19 @@ class ShowReactionsDialog(
}
override fun onClick(reactionItem: ReactionItem) {
if (hasChatPermission && reactionItem.reactionVoter.actorId?.equals(userEntity?.userId) == true) {
if (hasChatPermission && reactionItem.reactionVoter.actorId?.equals(user?.userId) == true) {
deleteReaction(chatMessage, reactionItem.reaction!!)
dismiss()
}
}
private fun deleteReaction(message: ChatMessage, emoji: String) {
val credentials = ApiUtils.getCredentials(userEntity?.username, userEntity?.token)
val credentials = ApiUtils.getCredentials(user?.username, user?.token)
ncApi.deleteReaction(
credentials,
ApiUtils.getUrlForMessageReaction(
userEntity?.baseUrl,
user?.baseUrl,
currentConversation!!.token,
message.id
),

View file

@ -32,6 +32,7 @@ import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.models.RetrofitBucket;
import com.nextcloud.talk.models.database.CapabilitiesUtil;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
import org.jetbrains.annotations.NotNull;
@ -181,6 +182,15 @@ public class ApiUtils {
throw new NoSupportedApiException();
}
/**
* migrate to {@link #getChatApiVersion(User, int[])}.
*
* @param user User
* @param versions API versions
* @return to be used verison
* @throws NoSupportedApiException if no supported version available
*/
@Deprecated
public static int getChatApiVersion(UserEntity user, int[] versions) throws NoSupportedApiException {
for (int version : versions) {
if (version == APIv1 && CapabilitiesUtil.hasSpreedFeatureCapability(user, "chat-v2")) {
@ -191,6 +201,16 @@ public class ApiUtils {
throw new NoSupportedApiException();
}
public static int getChatApiVersion(User user, int[] versions) throws NoSupportedApiException {
for (int version : versions) {
if (version == APIv1 && CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "chat-v2")) {
// Do not question that chat-v2 capability shows the availability of api/v1/ endpoint *see no evil*
return version;
}
}
throw new NoSupportedApiException();
}
protected static String getUrlForApi(int version, String baseUrl) {
return baseUrl + spreedApiBase + version;
}

View file

@ -20,8 +20,9 @@
package com.nextcloud.talk.utils
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
/**
* see https://nextcloud-talk.readthedocs.io/en/latest/constants/#attendee-permissions
@ -49,8 +50,13 @@ class AttendeePermissionsUtil(flag: Int) {
hasChatPermission = (flag and CHAT) == CHAT
}
@Deprecated("use hasChatPermission(user: User) instead")
fun hasChatPermission(user: UserEntity): Boolean {
if (CapabilitiesUtil.hasSpreedFeatureCapability(user, "chat-permission")) {
return hasChatPermission(LegacyUserEntityMapper.toModel(user)!!)
}
fun hasChatPermission(user: User): Boolean {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "chat-permission")) {
return hasChatPermission
}
// if capability is not available then the spreed version doesn't support to restrict this

View file

@ -193,12 +193,20 @@ public class DisplayUtils {
return bitmap;
}
public static ImageRequest getImageRequestForUrl(String url) {
return getImageRequestForUrl(url, (User) null);
}
public static ImageRequest getImageRequestForUrl(String url, @Nullable UserEntity userEntity) {
return getImageRequestForUrl(url, LegacyUserEntityMapper.toModel(userEntity));
}
public static ImageRequest getImageRequestForUrl(String url, @Nullable User user) {
Map<String, String> headers = new HashMap<>();
if (userEntity != null &&
url.startsWith(userEntity.getBaseUrl()) &&
if (user != null &&
url.startsWith(user.getBaseUrl()) &&
(url.contains("index.php/core/preview?fileId=") || url.contains("/avatar/"))) {
headers.put("Authorization", ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()));
headers.put("Authorization", ApiUtils.getCredentials(user.getUsername(), user.getToken()));
}
return ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
@ -289,8 +297,11 @@ public class DisplayUtils {
return drawable;
}
public static Drawable getDrawableForMentionChipSpan(Context context, String id, CharSequence label,
UserEntity conversationUser, String type,
public static Drawable getDrawableForMentionChipSpan(Context context,
String id,
CharSequence label,
User conversationUser,
String type,
@XmlRes int chipResource,
@Nullable EditText emojiEditText) {
ChipDrawable chip = ChipDrawable.createFromResource(context, chipResource);
@ -327,7 +338,7 @@ public class DisplayUtils {
conversationUser.getBaseUrl(),
String.valueOf(label), true);
}
ImageRequest imageRequest = getImageRequestForUrl(url, null);
ImageRequest imageRequest = getImageRequestForUrl(url);
ImagePipeline imagePipeline = Fresco.getImagePipeline();
DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(
imageRequest,
@ -361,7 +372,7 @@ public class DisplayUtils {
public static Spannable searchAndReplaceWithMentionSpan(Context context, Spannable text,
String id, String label, String type,
UserEntity conversationUser,
User conversationUser,
@XmlRes int chipXmlRes) {
Spannable spannableString = new SpannableString(text);
@ -599,7 +610,7 @@ public class DisplayUtils {
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setOldController(avatarImageView.getController())
.setAutoPlayAnimations(true)
.setImageRequest(DisplayUtils.getImageRequestForUrl(avatarString, null))
.setImageRequest(DisplayUtils.getImageRequestForUrl(avatarString))
.build();
avatarImageView.setController(draweeController);
}

View file

@ -42,14 +42,12 @@ import com.nextcloud.talk.activities.FullScreenImageActivity
import com.nextcloud.talk.activities.FullScreenMediaActivity
import com.nextcloud.talk.activities.FullScreenTextViewerActivity
import com.nextcloud.talk.adapters.messages.MagicPreviewMessageViewHolder
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.jobs.DownloadFileToCacheWorker
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.utils.AccountUtils.canWeOpenFilesApp
import com.nextcloud.talk.utils.Mimetype.AUDIO_MPEG
import com.nextcloud.talk.utils.Mimetype.AUDIO_OGG
import com.nextcloud.talk.utils.Mimetype.AUDIO_PREFIX
import com.nextcloud.talk.utils.Mimetype.AUDIO_WAV
import com.nextcloud.talk.utils.Mimetype.IMAGE_GIF
import com.nextcloud.talk.utils.Mimetype.IMAGE_JPEG
@ -59,8 +57,12 @@ import com.nextcloud.talk.utils.Mimetype.TEXT_PLAIN
import com.nextcloud.talk.utils.Mimetype.VIDEO_MP4
import com.nextcloud.talk.utils.Mimetype.VIDEO_OGG
import com.nextcloud.talk.utils.Mimetype.VIDEO_QUICKTIME
import com.nextcloud.talk.utils.MimetypeUtils.isAudioOnly
import com.nextcloud.talk.utils.MimetypeUtils.isGif
import com.nextcloud.talk.utils.MimetypeUtils.isMarkdown
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACCOUNT
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_ID
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import java.io.File
import java.util.concurrent.ExecutionException
@ -70,7 +72,7 @@ import java.util.concurrent.ExecutionException
* Example:
* - SharedItemsViewHolder
*/
class FileViewerUtils(private val context: Context, private val userEntity: UserEntity) {
class FileViewerUtils(private val context: Context, private val user: User) {
fun openFile(
message: ChatMessage,
@ -208,10 +210,10 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
}
fun openFileInFilesApp(link: String, keyID: String) {
val accountString = userEntity.username + "@" +
userEntity.baseUrl
.replace("https://", "")
.replace("http://", "")
val accountString = user.username + "@" +
user.baseUrl
?.replace("https://", "")
?.replace("http://", "")
if (canWeOpenFilesApp(context, accountString)) {
val filesAppIntent = Intent(Intent.ACTION_VIEW, null)
@ -276,18 +278,6 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
}
}
private fun isGif(mimetype: String): Boolean {
return IMAGE_GIF == mimetype
}
private fun isMarkdown(mimetype: String): Boolean {
return TEXT_MARKDOWN == mimetype
}
private fun isAudioOnly(mimetype: String): Boolean {
return mimetype.startsWith(AUDIO_PREFIX)
}
@SuppressLint("LongLogTag")
private fun downloadFileToCache(
fileInfo: FileInfo,
@ -318,11 +308,11 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
}
val data: Data = Data.Builder()
.putString(DownloadFileToCacheWorker.KEY_BASE_URL, userEntity.baseUrl)
.putString(DownloadFileToCacheWorker.KEY_USER_ID, userEntity.userId)
.putString(DownloadFileToCacheWorker.KEY_BASE_URL, user.baseUrl)
.putString(DownloadFileToCacheWorker.KEY_USER_ID, user.userId)
.putString(
DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER,
CapabilitiesUtil.getAttachmentFolder(userEntity)
CapabilitiesUtilNew.getAttachmentFolder(user)
)
.putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileInfo.fileName)
.putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)

View file

@ -0,0 +1,35 @@
/*
* Nextcloud Talk application
*
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <infoi@andy-scherzinger.de>
*
* model 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.
*
* model 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 model program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.utils
object MimetypeUtils {
fun isGif(mimetype: String): Boolean {
return Mimetype.IMAGE_GIF == mimetype
}
fun isMarkdown(mimetype: String): Boolean {
return Mimetype.TEXT_MARKDOWN == mimetype
}
fun isAudioOnly(mimetype: String): Boolean {
return mimetype.startsWith(Mimetype.AUDIO_PREFIX)
}
}

View file

@ -41,6 +41,7 @@ import com.facebook.imagepipeline.image.CloseableBitmap
import com.facebook.imagepipeline.postprocessors.RoundAsCirclePostprocessor
import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.RingtoneSettings
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.utils.bundle.BundleKeys
@ -189,7 +190,7 @@ object NotificationUtils {
private inline fun scanNotifications(
context: Context?,
conversationUser: UserEntity,
conversationUser: User,
callback: (
notificationManager: NotificationManager,
statusBarNotification: StatusBarNotification,
@ -218,13 +219,19 @@ object NotificationUtils {
}
fun cancelAllNotificationsForAccount(context: Context?, conversationUser: UserEntity) {
scanNotifications(context, conversationUser) { notificationManager, statusBarNotification, _ ->
scanNotifications(
context,
LegacyUserEntityMapper.toModel(conversationUser)!!
) { notificationManager, statusBarNotification, _ ->
notificationManager.cancel(statusBarNotification.id)
}
}
fun cancelExistingNotificationWithId(context: Context?, conversationUser: UserEntity, notificationId: Long?) {
scanNotifications(context, conversationUser) { notificationManager, statusBarNotification, notification ->
scanNotifications(
context,
LegacyUserEntityMapper.toModel(conversationUser)!!
) { notificationManager, statusBarNotification, notification ->
if (notificationId == notification.extras.getLong(BundleKeys.KEY_NOTIFICATION_ID)) {
notificationManager.cancel(statusBarNotification.id)
}
@ -236,7 +243,10 @@ object NotificationUtils {
conversationUser: UserEntity,
roomTokenOrId: String
): StatusBarNotification? {
scanNotifications(context, conversationUser) { _, statusBarNotification, notification ->
scanNotifications(
context,
LegacyUserEntityMapper.toModel(conversationUser)!!
) { _, statusBarNotification, notification ->
if (roomTokenOrId == notification.extras.getString(BundleKeys.KEY_ROOM_TOKEN)) {
return statusBarNotification
}
@ -246,7 +256,7 @@ object NotificationUtils {
fun cancelExistingNotificationsForRoom(
context: Context?,
conversationUser: UserEntity,
conversationUser: User,
roomTokenOrId: String
) {
scanNotifications(context, conversationUser) { notificationManager, statusBarNotification, notification ->
@ -313,7 +323,7 @@ object NotificationUtils {
fun loadAvatarSync(avatarUrl: String): IconCompat? {
// TODO - how to handle errors here?
var avatarIcon: IconCompat? = null
val imageRequest = DisplayUtils.getImageRequestForUrl(avatarUrl, null)
val imageRequest = DisplayUtils.getImageRequestForUrl(avatarUrl)
val dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, null)
val closeableImageRef = DataSources.waitForFinalResult(dataSource) as CloseableReference<CloseableBitmap>?
val bitmap = closeableImageRef?.get()?.underlyingBitmap

View file

@ -22,21 +22,22 @@ package com.nextcloud.talk.utils
import android.content.Context
import com.nextcloud.talk.R
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.users.UserManager
object ShareUtils {
fun getStringForIntent(
context: Context?,
password: String?,
userUtils: UserUtils?,
userManager: UserManager,
conversation: Conversation?
): String {
val userEntity = userUtils?.currentUser
val userEntity = userManager.currentUser.blockingGet()
var shareString = ""
if (userEntity != null && context != null) {
shareString = String.format(
context.resources.getString(R.string.nc_share_text),
userEntity.baseUrl, conversation?.token
userEntity.baseUrl,
conversation?.token
)
if (!password.isNullOrEmpty()) {
shareString += String.format(context.resources.getString(R.string.nc_share_text_pass), password)

View file

@ -36,6 +36,7 @@ object CapabilitiesUtilNew {
return false
}
@JvmStatic
fun isServerEOL(user: User): Boolean {
// Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018
return !hasSpreedFeatureCapability(user, "no-ping")
@ -50,16 +51,16 @@ object CapabilitiesUtilNew {
return hasSpreedFeatureCapability(user, "chat-read-marker")
}
fun hasSpreedFeatureCapability(user: User, capabilityName: String): Boolean {
if (user.capabilities?.spreedCapability?.features != null) {
@JvmStatic
fun hasSpreedFeatureCapability(user: User?, capabilityName: String): Boolean {
if (user?.capabilities?.spreedCapability?.features != null) {
return user.capabilities!!.spreedCapability!!.features!!.contains(capabilityName)
}
return false
}
fun getMessageMaxLength(user: User): Int {
val capabilities = user.capabilities!!
if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) {
fun getMessageMaxLength(user: User?): Int {
if (user?.capabilities?.spreedCapability?.config?.containsKey("chat") == true) {
val chatConfigHashMap = user.capabilities!!.spreedCapability!!.config!!["chat"]
if (chatConfigHashMap?.containsKey("max-length") == true) {
val chatSize = chatConfigHashMap["max-length"]!!.toInt()
@ -97,11 +98,13 @@ object CapabilitiesUtilNew {
return false
}
@JvmStatic
fun isUserStatusAvailable(user: User): Boolean {
return user.capabilities?.userStatusCapability?.enabled == true &&
user.capabilities?.userStatusCapability?.supportsEmoji == true
}
@JvmStatic
fun getAttachmentFolder(user: User): String? {
if (user.capabilities?.spreedCapability?.config?.containsKey("attachments") == true) {
val map = user.capabilities!!.spreedCapability!!.config!!["attachments"]
@ -112,8 +115,8 @@ object CapabilitiesUtilNew {
return "/Talk"
}
fun getServerName(user: User): String? {
if (user.capabilities?.themingCapability != null) {
fun getServerName(user: User?): String? {
if (user?.capabilities?.themingCapability != null) {
return user.capabilities!!.themingCapability!!.name
}
return ""
@ -129,8 +132,8 @@ object CapabilitiesUtilNew {
user.capabilities!!.provisioningCapability!!.accountPropertyScopesVersion!! > 1
}
fun isAbleToCall(user: User): Boolean {
if (user.capabilities != null) {
fun isAbleToCall(user: User?): Boolean {
if (user?.capabilities != null) {
val capabilities = user.capabilities
return if (
capabilities?.spreedCapability?.config?.containsKey("call") == true &&
@ -146,6 +149,7 @@ object CapabilitiesUtilNew {
return false
}
@JvmStatic
fun isUnifiedSearchAvailable(user: User): Boolean {
return hasSpreedFeatureCapability(user, "unified-search")
}

View file

@ -21,15 +21,16 @@
package com.nextcloud.talk.utils.preferences.preferencestorage;
import android.content.Context;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.data.user.model.User;
import com.yarolegovich.mp.io.StorageModule;
public class DatabaseStorageFactory implements StorageModule.Factory {
private UserEntity conversationUser;
private User conversationUser;
private String conversationToken;
public DatabaseStorageFactory(UserEntity conversationUser, String conversationToken) {
public DatabaseStorageFactory(User conversationUser, String conversationToken) {
this.conversationUser = conversationUser;
this.conversationToken = conversationToken;
}

View file

@ -28,12 +28,12 @@ import android.util.Log;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.models.database.ArbitraryStorageEntity;
import com.nextcloud.talk.models.database.CapabilitiesUtil;
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.database.arbitrarystorage.ArbitraryStorageUtils;
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
import com.yarolegovich.mp.io.StorageModule;
import org.jetbrains.annotations.NotNull;
@ -58,7 +58,7 @@ public class DatabaseStorageModule implements StorageModule {
NcApi ncApi;
private UserEntity conversationUser;
private User conversationUser;
private String conversationToken;
private long accountIdentifier;
@ -66,7 +66,7 @@ public class DatabaseStorageModule implements StorageModule {
private String messageNotificationLevel;
public DatabaseStorageModule(UserEntity conversationUser, String conversationToken) {
public DatabaseStorageModule(User conversationUser, String conversationToken) {
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
this.conversationUser = conversationUser;
@ -122,7 +122,7 @@ public class DatabaseStorageModule implements StorageModule {
if (!key.equals("message_notification_level")) {
arbitraryStorageUtils.storeStorageSetting(accountIdentifier, key, value, conversationToken);
} else {
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "notification-levels")) {
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")) {
if (!TextUtils.isEmpty(messageNotificationLevel) && !messageNotificationLevel.equals(value)) {
int intValue;
switch (value) {

View file

@ -20,13 +20,13 @@
package com.nextcloud.talk.utils.singletons;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.data.user.model.User;
public class ApplicationWideCurrentRoomHolder {
private static final ApplicationWideCurrentRoomHolder holder = new ApplicationWideCurrentRoomHolder();
private String currentRoomId = "";
private String currentRoomToken = "";
private UserEntity userInRoom = new UserEntity();
private User userInRoom = new User();
private boolean inCall = false;
private boolean isDialing = false;
private String session = "";
@ -37,7 +37,7 @@ public class ApplicationWideCurrentRoomHolder {
public void clear() {
currentRoomId = "";
userInRoom = new UserEntity();
userInRoom = new User();
inCall = false;
isDialing = false;
currentRoomToken = "";
@ -60,11 +60,11 @@ public class ApplicationWideCurrentRoomHolder {
this.currentRoomId = currentRoomId;
}
public UserEntity getUserInRoom() {
public User getUserInRoom() {
return userInRoom;
}
public void setUserInRoom(UserEntity userInRoom) {
public void setUserInRoom(User userInRoom) {
this.userInRoom = userInRoom;
}

View file

@ -22,11 +22,11 @@ package com.nextcloud.talk.utils
import android.content.Context
import android.content.res.Resources
import com.nextcloud.talk.R
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.users.UserManager
import io.reactivex.Maybe
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
@ -41,10 +41,10 @@ class ShareUtilsTest {
private val resources: Resources? = null
@Mock
private val userUtils: UserUtils? = null
private val userManager: UserManager? = null
@Mock
private val userEntity: UserEntity? = null
private val user: User? = null
private val baseUrl = "https://my.nextcloud.com"
private val token = "2aotbrjr"
@ -54,8 +54,8 @@ class ShareUtilsTest {
@Before
fun setUp() {
MockitoAnnotations.openMocks(this)
Mockito.`when`(userUtils!!.currentUser).thenReturn(userEntity)
Mockito.`when`(userEntity!!.baseUrl).thenReturn(baseUrl)
Mockito.`when`(userManager!!.currentUser).thenReturn(Maybe.just(user))
Mockito.`when`(user!!.baseUrl).thenReturn(baseUrl)
Mockito.`when`(context!!.resources).thenReturn(resources)
Mockito.`when`(resources!!.getString(R.string.nc_share_text))
.thenReturn("Join the conversation at %1\$s/index.php/call/%2\$s")
@ -72,7 +72,7 @@ class ShareUtilsTest {
)
Assert.assertEquals(
"Intent string was not as expected",
expectedResult, ShareUtils.getStringForIntent(context, "", userUtils, conversation)
expectedResult, ShareUtils.getStringForIntent(context, "", userManager!!, conversation)
)
}
@ -85,7 +85,7 @@ class ShareUtilsTest {
)
Assert.assertEquals(
"Intent string was not as expected",
expectedResult, ShareUtils.getStringForIntent(context, password, userUtils, conversation)
expectedResult, ShareUtils.getStringForIntent(context, password, userManager!!, conversation)
)
}
}

View file

@ -0,0 +1 @@
mock-maker-inline

View file

@ -1,5 +1,5 @@
build:
maxIssues: 88
maxIssues: 86
weights:
# complexity: 2
# LongParameterList: 1

View file

@ -1 +1 @@
162
154