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