diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt index b787b7afe..06a454703 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt @@ -303,7 +303,7 @@ class CallActivity : CallBaseActivity() { private var handler: Handler? = null private var currentCallStatus: CallStatus? = null private var mediaPlayer: MediaPlayer? = null - private var participantDisplayItems: MutableMap? = null + private var participantDisplayItems: MutableMap? = null private var participantsAdapter: ParticipantsAdapter? = null private var binding: CallActivityBinding? = null private var audioOutputDialog: AudioOutputDialog? = null @@ -994,7 +994,7 @@ class CallActivity : CallBaseActivity() { } participantsAdapter = ParticipantsAdapter( this, - participantDisplayItems, + participantDisplayItems!!.toMap(), binding!!.conversationRelativeLayout, binding!!.callInfosLinearLayout, columns, diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantsAdapter.kt b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantsAdapter.kt index c6c49773d..69dfead61 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantsAdapter.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantsAdapter.kt @@ -5,213 +5,200 @@ * SPDX-FileCopyrightText: 2022 Daniel Calviño Sánchez * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.adapters; +package com.nextcloud.talk.adapters -import android.content.Context; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; +import android.content.Context +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.ProgressBar +import android.widget.RelativeLayout +import android.widget.TextView +import com.nextcloud.talk.R +import com.nextcloud.talk.activities.CallActivity +import com.nextcloud.talk.extensions.loadAvatarWithUrl +import com.nextcloud.talk.extensions.loadFirstLetterAvatar +import com.nextcloud.talk.models.json.participants.Participant +import org.webrtc.MediaStream +import org.webrtc.MediaStreamTrack +import org.webrtc.RendererCommon +import org.webrtc.SurfaceViewRenderer +import kotlin.math.ceil -import com.nextcloud.talk.R; -import com.nextcloud.talk.activities.CallActivity; -import com.nextcloud.talk.extensions.ImageViewExtensionsKt; -import com.nextcloud.talk.models.json.participants.Participant; +class ParticipantsAdapter( + private val mContext: Context, + participantDisplayItems: Map, + private val gridViewWrapper: RelativeLayout, + private val callInfosLinearLayout: LinearLayout, + private val columns: Int, + private val isVoiceOnlyCall: Boolean +) : BaseAdapter() { + private val participantDisplayItemObserver = ParticipantDisplayItem.Observer { this.notifyDataSetChanged() } -import org.webrtc.MediaStream; -import org.webrtc.MediaStreamTrack; -import org.webrtc.RendererCommon; -import org.webrtc.SurfaceViewRenderer; -import org.webrtc.VideoTrack; + private val participantDisplayItems = ArrayList() -import java.util.ArrayList; -import java.util.Map; + init { + this.participantDisplayItems.addAll(participantDisplayItems.values) -public class ParticipantsAdapter extends BaseAdapter { - - private static final String TAG = "ParticipantsAdapter"; - - private final ParticipantDisplayItem.Observer participantDisplayItemObserver = this::notifyDataSetChanged; - - private final Context mContext; - private final ArrayList participantDisplayItems; - private final RelativeLayout gridViewWrapper; - private final LinearLayout callInfosLinearLayout; - private final int columns; - private final boolean isVoiceOnlyCall; - - public ParticipantsAdapter(Context mContext, - Map participantDisplayItems, - RelativeLayout gridViewWrapper, - LinearLayout callInfosLinearLayout, - int columns, - boolean isVoiceOnlyCall) { - this.mContext = mContext; - this.gridViewWrapper = gridViewWrapper; - this.callInfosLinearLayout = callInfosLinearLayout; - this.columns = columns; - this.isVoiceOnlyCall = isVoiceOnlyCall; - - this.participantDisplayItems = new ArrayList<>(); - this.participantDisplayItems.addAll(participantDisplayItems.values()); - - for (ParticipantDisplayItem participantDisplayItem : this.participantDisplayItems) { - participantDisplayItem.addObserver(participantDisplayItemObserver); + for (participantDisplayItem in this.participantDisplayItems) { + participantDisplayItem.addObserver(participantDisplayItemObserver) } } - public void destroy() { - for (ParticipantDisplayItem participantDisplayItem : participantDisplayItems) { - participantDisplayItem.removeObserver(participantDisplayItemObserver); + fun destroy() { + for (participantDisplayItem in participantDisplayItems) { + participantDisplayItem.removeObserver(participantDisplayItemObserver) } } - @Override - public int getCount() { - return participantDisplayItems.size(); + override fun getCount(): Int { + return participantDisplayItems.size } - @Override - public ParticipantDisplayItem getItem(int position) { - return participantDisplayItems.get(position); + override fun getItem(position: Int): ParticipantDisplayItem { + return participantDisplayItems[position] } - @Override - public long getItemId(int position) { - return 0; + override fun getItemId(position: Int): Long { + return 0 } - @Override - public View getView(int position, View convertView, ViewGroup parent) { - ParticipantDisplayItem participantDisplayItem = getItem(position); + @Suppress("Detekt.LongMethod", "Detekt.TooGenericExceptionCaught") + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + var convertView = convertView + val participantDisplayItem = getItem(position) - SurfaceViewRenderer surfaceViewRenderer; + val surfaceViewRenderer: SurfaceViewRenderer if (convertView == null) { - convertView = LayoutInflater.from(mContext).inflate(R.layout.call_item, parent, false); - convertView.setVisibility(View.VISIBLE); + convertView = LayoutInflater.from(mContext).inflate(R.layout.call_item, parent, false) + convertView.visibility = View.VISIBLE - surfaceViewRenderer = convertView.findViewById(R.id.surface_view); + surfaceViewRenderer = convertView.findViewById(R.id.surface_view) try { - Log.d(TAG, "hasSurface: " + participantDisplayItem.getRootEglBase().hasSurface()); + Log.d(TAG, "hasSurface: " + participantDisplayItem.rootEglBase.hasSurface()) - surfaceViewRenderer.setMirror(false); - surfaceViewRenderer.init(participantDisplayItem.getRootEglBase().getEglBaseContext(), null); - surfaceViewRenderer.setZOrderMediaOverlay(false); + surfaceViewRenderer.setMirror(false) + surfaceViewRenderer.init(participantDisplayItem.rootEglBase.eglBaseContext, null) + surfaceViewRenderer.setZOrderMediaOverlay(false) // disabled because it causes some devices to crash - surfaceViewRenderer.setEnableHardwareScaler(false); - surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); - } catch (Exception e) { - Log.e(TAG, "error while initializing surfaceViewRenderer", e); + surfaceViewRenderer.setEnableHardwareScaler(false) + surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) + } catch (e: Exception) { + Log.e(TAG, "error while initializing surfaceViewRenderer", e) } } else { - surfaceViewRenderer = convertView.findViewById(R.id.surface_view); + surfaceViewRenderer = convertView.findViewById(R.id.surface_view) } - ProgressBar progressBar = convertView.findViewById(R.id.participant_progress_bar); - if (!participantDisplayItem.isConnected()) { - progressBar.setVisibility(View.VISIBLE); + val progressBar = convertView!!.findViewById(R.id.participant_progress_bar) + if (!participantDisplayItem.isConnected) { + progressBar.visibility = View.VISIBLE } else { - progressBar.setVisibility(View.GONE); + progressBar.visibility = View.GONE } - ViewGroup.LayoutParams layoutParams = convertView.getLayoutParams(); - layoutParams.height = scaleGridViewItemHeight(); - convertView.setLayoutParams(layoutParams); + val layoutParams = convertView.layoutParams + layoutParams.height = scaleGridViewItemHeight() + convertView.layoutParams = layoutParams - TextView nickTextView = convertView.findViewById(R.id.peer_nick_text_view); - ImageView imageView = convertView.findViewById(R.id.avatarImageView); + val nickTextView = convertView.findViewById(R.id.peer_nick_text_view) + val imageView = convertView.findViewById(R.id.avatarImageView) - MediaStream mediaStream = participantDisplayItem.getMediaStream(); + val mediaStream = participantDisplayItem.mediaStream if (hasVideoStream(participantDisplayItem, mediaStream)) { - VideoTrack videoTrack = mediaStream.videoTracks.get(0); - videoTrack.addSink(surfaceViewRenderer); - imageView.setVisibility(View.INVISIBLE); - surfaceViewRenderer.setVisibility(View.VISIBLE); - nickTextView.setVisibility(View.GONE); + val videoTrack = mediaStream.videoTracks[0] + videoTrack.addSink(surfaceViewRenderer) + imageView.visibility = View.INVISIBLE + surfaceViewRenderer.visibility = View.VISIBLE + nickTextView.visibility = View.GONE } else { - imageView.setVisibility(View.VISIBLE); - surfaceViewRenderer.setVisibility(View.INVISIBLE); + imageView.visibility = View.VISIBLE + surfaceViewRenderer.visibility = View.INVISIBLE - if (((CallActivity) mContext).isInPipMode) { - nickTextView.setVisibility(View.GONE); + if ((mContext as CallActivity).isInPipMode) { + nickTextView.visibility = View.GONE } else { - nickTextView.setVisibility(View.VISIBLE); - nickTextView.setText(participantDisplayItem.getNick()); + nickTextView.visibility = View.VISIBLE + nickTextView.text = participantDisplayItem.nick } - if (participantDisplayItem.getActorType() == Participant.ActorType.GUESTS || - participantDisplayItem.getActorType() == Participant.ActorType.EMAILS) { - ImageViewExtensionsKt.loadFirstLetterAvatar( - imageView, - String.valueOf(participantDisplayItem.getNick()) - ); + if (participantDisplayItem.actorType == Participant.ActorType.GUESTS || + participantDisplayItem.actorType == Participant.ActorType.EMAILS + ) { + imageView + .loadFirstLetterAvatar( + participantDisplayItem.nick.toString() + ) } else { - ImageViewExtensionsKt.loadAvatarWithUrl(imageView,null, participantDisplayItem.getUrlForAvatar()); + imageView.loadAvatarWithUrl(null, participantDisplayItem.urlForAvatar) } } - ImageView audioOffView = convertView.findViewById(R.id.remote_audio_off); - if (!participantDisplayItem.isAudioEnabled()) { - audioOffView.setVisibility(View.VISIBLE); + val audioOffView = convertView.findViewById(R.id.remote_audio_off) + if (!participantDisplayItem.isAudioEnabled) { + audioOffView.visibility = View.VISIBLE } else { - audioOffView.setVisibility(View.GONE); + audioOffView.visibility = View.GONE } - ImageView raisedHandView = convertView.findViewById(R.id.raised_hand); - if (participantDisplayItem.getRaisedHand() != null && participantDisplayItem.getRaisedHand().getState()) { - raisedHandView.setVisibility(View.VISIBLE); + val raisedHandView = convertView.findViewById(R.id.raised_hand) + if (participantDisplayItem.raisedHand != null && participantDisplayItem.raisedHand.state) { + raisedHandView.visibility = View.VISIBLE } else { - raisedHandView.setVisibility(View.GONE); + raisedHandView.visibility = View.GONE } - return convertView; + return convertView } - private boolean hasVideoStream(ParticipantDisplayItem participantDisplayItem, MediaStream mediaStream) { - if (!participantDisplayItem.isStreamEnabled()) { - return false; + @Suppress("ReturnCount") + private fun hasVideoStream(participantDisplayItem: ParticipantDisplayItem, mediaStream: MediaStream?): Boolean { + if (!participantDisplayItem.isStreamEnabled) { + return false } - if (mediaStream == null || mediaStream.videoTracks == null) { - return false; + if (mediaStream?.videoTracks == null) { + return false } - for (VideoTrack t : mediaStream.videoTracks) { + for (t in mediaStream.videoTracks) { if (MediaStreamTrack.State.LIVE == t.state()) { - return true; + return true } } - return false; + return false } - private int scaleGridViewItemHeight() { - int headerHeight = 0; - int callControlsHeight = 0; - if (callInfosLinearLayout.getVisibility() == View.VISIBLE && isVoiceOnlyCall) { - headerHeight = callInfosLinearLayout.getHeight(); + private fun scaleGridViewItemHeight(): Int { + var headerHeight = 0 + var callControlsHeight = 0 + if (callInfosLinearLayout.visibility == View.VISIBLE && isVoiceOnlyCall) { + headerHeight = callInfosLinearLayout.height } if (isVoiceOnlyCall) { - callControlsHeight = Math.round(mContext.getResources().getDimension(R.dimen.call_controls_height)); + callControlsHeight = Math.round(mContext.resources.getDimension(R.dimen.call_controls_height)) } - int itemHeight = (gridViewWrapper.getHeight() - headerHeight - callControlsHeight) / getRowsCount(getCount()); - int itemMinHeight = Math.round(mContext.getResources().getDimension(R.dimen.call_grid_item_min_height)); + var itemHeight = (gridViewWrapper.height - headerHeight - callControlsHeight) / getRowsCount(count) + val itemMinHeight = Math.round(mContext.resources.getDimension(R.dimen.call_grid_item_min_height)) if (itemHeight < itemMinHeight) { - itemHeight = itemMinHeight; + itemHeight = itemMinHeight } - return itemHeight; + return itemHeight } - private int getRowsCount(int items) { - int rows = (int) Math.ceil((double) items / (double) columns); + private fun getRowsCount(items: Int): Int { + var rows = ceil(items.toDouble() / columns.toDouble()).toInt() if (rows == 0) { - rows = 1; + rows = 1 } - return rows; + return rows + } + + companion object { + private const val TAG = "ParticipantsAdapter" } }