mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-09-18 07:22:26 +00:00
Added new casting dialog.
This commit is contained in:
parent
5b143bdc76
commit
ee7b89ec6e
9 changed files with 375 additions and 340 deletions
|
@ -69,7 +69,6 @@ class StateCasting {
|
||||||
private var _started = false;
|
private var _started = false;
|
||||||
|
|
||||||
var devices: HashMap<String, CastingDevice> = hashMapOf();
|
var devices: HashMap<String, CastingDevice> = hashMapOf();
|
||||||
var rememberedDevices: ArrayList<CastingDevice> = arrayListOf();
|
|
||||||
val onDeviceAdded = Event1<CastingDevice>();
|
val onDeviceAdded = Event1<CastingDevice>();
|
||||||
val onDeviceChanged = Event1<CastingDevice>();
|
val onDeviceChanged = Event1<CastingDevice>();
|
||||||
val onDeviceRemoved = Event1<CastingDevice>();
|
val onDeviceRemoved = Event1<CastingDevice>();
|
||||||
|
@ -156,9 +155,6 @@ class StateCasting {
|
||||||
|
|
||||||
Logger.i(TAG, "CastingService starting...");
|
Logger.i(TAG, "CastingService starting...");
|
||||||
|
|
||||||
rememberedDevices.clear();
|
|
||||||
rememberedDevices.addAll(_storage.deviceInfos.map { deviceFromCastingDeviceInfo(it) });
|
|
||||||
|
|
||||||
_castServer.start();
|
_castServer.start();
|
||||||
enableDeveloper(true);
|
enableDeveloper(true);
|
||||||
|
|
||||||
|
@ -370,9 +366,6 @@ class StateCasting {
|
||||||
invokeInMainScopeIfRequired { onActiveDeviceTimeChanged.emit(it) };
|
invokeInMainScopeIfRequired { onActiveDeviceTimeChanged.emit(it) };
|
||||||
};
|
};
|
||||||
|
|
||||||
addRememberedDevice(device);
|
|
||||||
Logger.i(TAG, "Device added to active discovery. Active discovery now contains ${_storage.getDevicesCount()} devices.")
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
device.start();
|
device.start();
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
@ -394,21 +387,22 @@ class StateCasting {
|
||||||
return addRememberedDevice(device);
|
return addRememberedDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getRememberedCastingDevices(): List<CastingDevice> {
|
||||||
|
return _storage.getDevices().map { deviceFromCastingDeviceInfo(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRememberedCastingDeviceNames(): List<String> {
|
||||||
|
return _storage.getDeviceNames()
|
||||||
|
}
|
||||||
|
|
||||||
fun addRememberedDevice(device: CastingDevice): CastingDeviceInfo {
|
fun addRememberedDevice(device: CastingDevice): CastingDeviceInfo {
|
||||||
val deviceInfo = device.getDeviceInfo()
|
val deviceInfo = device.getDeviceInfo()
|
||||||
val foundInfo = _storage.addDevice(deviceInfo)
|
return _storage.addDevice(deviceInfo)
|
||||||
if (foundInfo == deviceInfo) {
|
|
||||||
rememberedDevices.add(device);
|
|
||||||
return foundInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return foundInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeRememberedDevice(device: CastingDevice) {
|
fun removeRememberedDevice(device: CastingDevice) {
|
||||||
val name = device.name ?: return;
|
val name = device.name ?: return
|
||||||
_storage.removeDevice(name);
|
_storage.removeDevice(name)
|
||||||
rememberedDevices.remove(device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun invokeInMainScopeIfRequired(action: () -> Unit){
|
private fun invokeInMainScopeIfRequired(action: () -> Unit){
|
||||||
|
|
|
@ -9,7 +9,9 @@ import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.futo.platformplayer.R
|
import com.futo.platformplayer.R
|
||||||
|
@ -21,22 +23,21 @@ import com.futo.platformplayer.casting.StateCasting
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.states.StateApp
|
import com.futo.platformplayer.states.StateApp
|
||||||
import com.futo.platformplayer.views.adapters.DeviceAdapter
|
import com.futo.platformplayer.views.adapters.DeviceAdapter
|
||||||
|
import com.futo.platformplayer.views.adapters.DeviceAdapterEntry
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class ConnectCastingDialog(context: Context?) : AlertDialog(context) {
|
class ConnectCastingDialog(context: Context?) : AlertDialog(context) {
|
||||||
private lateinit var _imageLoader: ImageView;
|
private lateinit var _imageLoader: ImageView;
|
||||||
private lateinit var _buttonClose: Button;
|
private lateinit var _buttonClose: Button;
|
||||||
private lateinit var _buttonAdd: ImageButton;
|
private lateinit var _buttonAdd: LinearLayout;
|
||||||
private lateinit var _buttonScanQR: ImageButton;
|
private lateinit var _buttonScanQR: LinearLayout;
|
||||||
private lateinit var _textNoDevicesFound: TextView;
|
private lateinit var _textNoDevicesFound: TextView;
|
||||||
private lateinit var _textNoDevicesRemembered: TextView;
|
|
||||||
private lateinit var _recyclerDevices: RecyclerView;
|
private lateinit var _recyclerDevices: RecyclerView;
|
||||||
private lateinit var _recyclerRememberedDevices: RecyclerView;
|
|
||||||
private lateinit var _adapter: DeviceAdapter;
|
private lateinit var _adapter: DeviceAdapter;
|
||||||
private lateinit var _rememberedAdapter: DeviceAdapter;
|
private val _devices: MutableSet<String> = mutableSetOf()
|
||||||
private val _devices: ArrayList<CastingDevice> = arrayListOf();
|
private val _rememberedDevices: MutableSet<String> = mutableSetOf()
|
||||||
private val _rememberedDevices: ArrayList<CastingDevice> = arrayListOf();
|
private val _unifiedDevices: MutableList<DeviceAdapterEntry> = mutableListOf()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -45,42 +46,40 @@ class ConnectCastingDialog(context: Context?) : AlertDialog(context) {
|
||||||
_imageLoader = findViewById(R.id.image_loader);
|
_imageLoader = findViewById(R.id.image_loader);
|
||||||
_buttonClose = findViewById(R.id.button_close);
|
_buttonClose = findViewById(R.id.button_close);
|
||||||
_buttonAdd = findViewById(R.id.button_add);
|
_buttonAdd = findViewById(R.id.button_add);
|
||||||
_buttonScanQR = findViewById(R.id.button_scan_qr);
|
_buttonScanQR = findViewById(R.id.button_qr);
|
||||||
_recyclerDevices = findViewById(R.id.recycler_devices);
|
_recyclerDevices = findViewById(R.id.recycler_devices);
|
||||||
_recyclerRememberedDevices = findViewById(R.id.recycler_remembered_devices);
|
|
||||||
_textNoDevicesFound = findViewById(R.id.text_no_devices_found);
|
_textNoDevicesFound = findViewById(R.id.text_no_devices_found);
|
||||||
_textNoDevicesRemembered = findViewById(R.id.text_no_devices_remembered);
|
|
||||||
|
|
||||||
_adapter = DeviceAdapter(_devices, false);
|
_adapter = DeviceAdapter(_unifiedDevices)
|
||||||
_recyclerDevices.adapter = _adapter;
|
_recyclerDevices.adapter = _adapter;
|
||||||
_recyclerDevices.layoutManager = LinearLayoutManager(context);
|
_recyclerDevices.layoutManager = LinearLayoutManager(context);
|
||||||
|
|
||||||
_rememberedAdapter = DeviceAdapter(_rememberedDevices, true);
|
_adapter.onPin.subscribe { d ->
|
||||||
_rememberedAdapter.onRemove.subscribe { d ->
|
val isRemembered = _rememberedDevices.contains(d.name)
|
||||||
if (StateCasting.instance.activeDevice == d) {
|
val newIsRemembered = !isRemembered
|
||||||
d.stopCasting();
|
if (newIsRemembered) {
|
||||||
|
StateCasting.instance.addRememberedDevice(d)
|
||||||
|
val name = d.name
|
||||||
|
if (name != null) {
|
||||||
|
_rememberedDevices.add(name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
StateCasting.instance.removeRememberedDevice(d)
|
||||||
|
_rememberedDevices.remove(d.name)
|
||||||
}
|
}
|
||||||
|
updateUnifiedList()
|
||||||
StateCasting.instance.removeRememberedDevice(d);
|
|
||||||
val index = _rememberedDevices.indexOf(d);
|
|
||||||
if (index != -1) {
|
|
||||||
_rememberedDevices.removeAt(index);
|
|
||||||
_rememberedAdapter.notifyItemRemoved(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
_textNoDevicesRemembered.visibility = if (_rememberedDevices.isEmpty()) View.VISIBLE else View.GONE;
|
|
||||||
_recyclerRememberedDevices.visibility = if (_rememberedDevices.isNotEmpty()) View.VISIBLE else View.GONE;
|
|
||||||
};
|
|
||||||
_rememberedAdapter.onConnect.subscribe { _ ->
|
|
||||||
dismiss()
|
|
||||||
//UIDialogs.showCastingDialog(context)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Integrate remembered into the main list
|
||||||
|
//TODO: Add green indicator to indicate a device is oneline
|
||||||
|
//TODO: Add pinning
|
||||||
|
//TODO: Implement QR code as an option in add manually
|
||||||
|
//TODO: Remove start button
|
||||||
|
|
||||||
_adapter.onConnect.subscribe { _ ->
|
_adapter.onConnect.subscribe { _ ->
|
||||||
dismiss()
|
dismiss()
|
||||||
//UIDialogs.showCastingDialog(context)
|
//UIDialogs.showCastingDialog(context)
|
||||||
}
|
}
|
||||||
_recyclerRememberedDevices.adapter = _rememberedAdapter;
|
|
||||||
_recyclerRememberedDevices.layoutManager = LinearLayoutManager(context);
|
|
||||||
|
|
||||||
_buttonClose.setOnClickListener { dismiss(); };
|
_buttonClose.setOnClickListener { dismiss(); };
|
||||||
_buttonAdd.setOnClickListener {
|
_buttonAdd.setOnClickListener {
|
||||||
|
@ -105,77 +104,112 @@ class ConnectCastingDialog(context: Context?) : AlertDialog(context) {
|
||||||
Logger.i(TAG, "Dialog shown.");
|
Logger.i(TAG, "Dialog shown.");
|
||||||
|
|
||||||
StateCasting.instance.startDiscovering()
|
StateCasting.instance.startDiscovering()
|
||||||
|
|
||||||
(_imageLoader.drawable as Animatable?)?.start();
|
(_imageLoader.drawable as Animatable?)?.start();
|
||||||
|
|
||||||
_devices.clear();
|
synchronized(StateCasting.instance.devices) {
|
||||||
synchronized (StateCasting.instance.devices) {
|
_devices.addAll(StateCasting.instance.devices.values.mapNotNull { it.name })
|
||||||
_devices.addAll(StateCasting.instance.devices.values);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_rememberedDevices.clear();
|
_rememberedDevices.addAll(StateCasting.instance.getRememberedCastingDeviceNames())
|
||||||
synchronized (StateCasting.instance.rememberedDevices) {
|
updateUnifiedList()
|
||||||
_rememberedDevices.addAll(StateCasting.instance.rememberedDevices);
|
|
||||||
|
StateCasting.instance.onDeviceAdded.subscribe(this) { d ->
|
||||||
|
val name = d.name
|
||||||
|
if (name != null)
|
||||||
|
_devices.add(name)
|
||||||
|
updateUnifiedList()
|
||||||
|
}
|
||||||
|
|
||||||
|
StateCasting.instance.onDeviceChanged.subscribe(this) { d ->
|
||||||
|
val index = _unifiedDevices.indexOfFirst { it.castingDevice.name == d.name }
|
||||||
|
if (index != -1) {
|
||||||
|
_unifiedDevices[index] = DeviceAdapterEntry(d, _unifiedDevices[index].isPinnedDevice, _unifiedDevices[index].isOnlineDevice)
|
||||||
|
_adapter.notifyItemChanged(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateCasting.instance.onDeviceRemoved.subscribe(this) { d ->
|
||||||
|
_devices.remove(d.name)
|
||||||
|
updateUnifiedList()
|
||||||
|
}
|
||||||
|
|
||||||
|
StateCasting.instance.onActiveDeviceConnectionStateChanged.subscribe(this) { _, connectionState ->
|
||||||
|
if (connectionState == CastConnectionState.CONNECTED) {
|
||||||
|
StateApp.instance.scopeOrNull?.launch(Dispatchers.Main) {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_textNoDevicesFound.visibility = if (_devices.isEmpty()) View.VISIBLE else View.GONE;
|
_textNoDevicesFound.visibility = if (_devices.isEmpty()) View.VISIBLE else View.GONE;
|
||||||
_recyclerDevices.visibility = if (_devices.isNotEmpty()) View.VISIBLE else View.GONE;
|
_recyclerDevices.visibility = if (_devices.isNotEmpty()) View.VISIBLE else View.GONE;
|
||||||
_textNoDevicesRemembered.visibility = if (_rememberedDevices.isEmpty()) View.VISIBLE else View.GONE;
|
|
||||||
_recyclerRememberedDevices.visibility = if (_rememberedDevices.isNotEmpty()) View.VISIBLE else View.GONE;
|
|
||||||
|
|
||||||
StateCasting.instance.onDeviceAdded.subscribe(this) { d ->
|
|
||||||
_devices.add(d);
|
|
||||||
_adapter.notifyItemInserted(_devices.size - 1);
|
|
||||||
_textNoDevicesFound.visibility = View.GONE;
|
|
||||||
_recyclerDevices.visibility = View.VISIBLE;
|
|
||||||
};
|
|
||||||
|
|
||||||
StateCasting.instance.onDeviceChanged.subscribe(this) { d ->
|
|
||||||
val index = _devices.indexOf(d);
|
|
||||||
if (index == -1) {
|
|
||||||
return@subscribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
_devices[index] = d;
|
|
||||||
_adapter.notifyItemChanged(index);
|
|
||||||
};
|
|
||||||
|
|
||||||
StateCasting.instance.onDeviceRemoved.subscribe(this) { d ->
|
|
||||||
val index = _devices.indexOf(d);
|
|
||||||
if (index == -1) {
|
|
||||||
return@subscribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
_devices.removeAt(index);
|
|
||||||
_adapter.notifyItemRemoved(index);
|
|
||||||
_textNoDevicesFound.visibility = if (_devices.isEmpty()) View.VISIBLE else View.GONE;
|
|
||||||
_recyclerDevices.visibility = if (_devices.isNotEmpty()) View.VISIBLE else View.GONE;
|
|
||||||
};
|
|
||||||
|
|
||||||
StateCasting.instance.onActiveDeviceConnectionStateChanged.subscribe(this) { _, connectionState ->
|
|
||||||
if (connectionState != CastConnectionState.CONNECTED) {
|
|
||||||
return@subscribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateApp.instance.scopeOrNull?.launch(Dispatchers.Main) {
|
|
||||||
dismiss();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
_adapter.notifyDataSetChanged();
|
|
||||||
_rememberedAdapter.notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dismiss() {
|
override fun dismiss() {
|
||||||
super.dismiss();
|
super.dismiss()
|
||||||
|
(_imageLoader.drawable as Animatable?)?.stop()
|
||||||
(_imageLoader.drawable as Animatable?)?.stop();
|
|
||||||
|
|
||||||
StateCasting.instance.stopDiscovering()
|
StateCasting.instance.stopDiscovering()
|
||||||
StateCasting.instance.onDeviceAdded.remove(this);
|
StateCasting.instance.onDeviceAdded.remove(this)
|
||||||
StateCasting.instance.onDeviceChanged.remove(this);
|
StateCasting.instance.onDeviceChanged.remove(this)
|
||||||
StateCasting.instance.onDeviceRemoved.remove(this);
|
StateCasting.instance.onDeviceRemoved.remove(this)
|
||||||
StateCasting.instance.onActiveDeviceConnectionStateChanged.remove(this);
|
StateCasting.instance.onActiveDeviceConnectionStateChanged.remove(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateUnifiedList() {
|
||||||
|
val oldList = ArrayList(_unifiedDevices)
|
||||||
|
val newList = buildUnifiedList()
|
||||||
|
|
||||||
|
val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
|
||||||
|
override fun getOldListSize() = oldList.size
|
||||||
|
override fun getNewListSize() = newList.size
|
||||||
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||||
|
val oldItem = oldList[oldItemPosition]
|
||||||
|
val newItem = newList[newItemPosition]
|
||||||
|
return oldItem.castingDevice.name == newItem.castingDevice.name
|
||||||
|
&& oldItem.castingDevice.isReady == newItem.castingDevice.isReady
|
||||||
|
&& oldItem.isOnlineDevice == newItem.isOnlineDevice
|
||||||
|
&& oldItem.isPinnedDevice == newItem.isPinnedDevice
|
||||||
|
}
|
||||||
|
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||||
|
val oldItem = oldList[oldItemPosition]
|
||||||
|
val newItem = newList[newItemPosition]
|
||||||
|
return oldItem.castingDevice.name == newItem.castingDevice.name
|
||||||
|
&& oldItem.castingDevice.isReady == newItem.castingDevice.isReady
|
||||||
|
&& oldItem.isOnlineDevice == newItem.isOnlineDevice
|
||||||
|
&& oldItem.isPinnedDevice == newItem.isPinnedDevice
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
_unifiedDevices.clear()
|
||||||
|
_unifiedDevices.addAll(newList)
|
||||||
|
diffResult.dispatchUpdatesTo(_adapter)
|
||||||
|
|
||||||
|
_textNoDevicesFound.visibility = if (_unifiedDevices.isEmpty()) View.VISIBLE else View.GONE
|
||||||
|
_recyclerDevices.visibility = if (_unifiedDevices.isNotEmpty()) View.VISIBLE else View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildUnifiedList(): List<DeviceAdapterEntry> {
|
||||||
|
val onlineDevices = StateCasting.instance.devices.values.associateBy { it.name }
|
||||||
|
val rememberedDevices = StateCasting.instance.getRememberedCastingDevices().associateBy { it.name }
|
||||||
|
|
||||||
|
val unifiedList = mutableListOf<DeviceAdapterEntry>()
|
||||||
|
|
||||||
|
val intersectionNames = _devices.intersect(_rememberedDevices)
|
||||||
|
for (name in intersectionNames) {
|
||||||
|
onlineDevices[name]?.let { unifiedList.add(DeviceAdapterEntry(it, true, true)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val onlineOnlyNames = _devices - _rememberedDevices
|
||||||
|
for (name in onlineOnlyNames) {
|
||||||
|
onlineDevices[name]?.let { unifiedList.add(DeviceAdapterEntry(it, false, true)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val rememberedOnlyNames = _rememberedDevices - _devices
|
||||||
|
for (name in rememberedOnlyNames) {
|
||||||
|
rememberedDevices[name]?.let { unifiedList.add(DeviceAdapterEntry(it, true, false)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return unifiedList
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -19,6 +19,11 @@ class CastingDeviceInfoStorage : FragmentedStorageFileJson() {
|
||||||
return deviceInfos.toList();
|
return deviceInfos.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
fun getDeviceNames() : List<String> {
|
||||||
|
return deviceInfos.map { it.name }.toList();
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun addDevice(castingDeviceInfo: CastingDeviceInfo): CastingDeviceInfo {
|
fun addDevice(castingDeviceInfo: CastingDeviceInfo): CastingDeviceInfo {
|
||||||
val foundDeviceInfo = deviceInfos.firstOrNull { d -> d.name == castingDeviceInfo.name }
|
val foundDeviceInfo = deviceInfos.firstOrNull { d -> d.name == castingDeviceInfo.name }
|
||||||
|
|
|
@ -7,16 +7,16 @@ import com.futo.platformplayer.R
|
||||||
import com.futo.platformplayer.casting.CastingDevice
|
import com.futo.platformplayer.casting.CastingDevice
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
|
||||||
class DeviceAdapter : RecyclerView.Adapter<DeviceViewHolder> {
|
data class DeviceAdapterEntry(val castingDevice: CastingDevice, val isPinnedDevice: Boolean, val isOnlineDevice: Boolean)
|
||||||
private val _devices: ArrayList<CastingDevice>;
|
|
||||||
private val _isRememberedDevice: Boolean;
|
|
||||||
|
|
||||||
var onRemove = Event1<CastingDevice>();
|
class DeviceAdapter : RecyclerView.Adapter<DeviceViewHolder> {
|
||||||
|
private val _devices: List<DeviceAdapterEntry>;
|
||||||
|
|
||||||
|
var onPin = Event1<CastingDevice>();
|
||||||
var onConnect = Event1<CastingDevice>();
|
var onConnect = Event1<CastingDevice>();
|
||||||
|
|
||||||
constructor(devices: ArrayList<CastingDevice>, isRememberedDevice: Boolean) : super() {
|
constructor(devices: List<DeviceAdapterEntry>) : super() {
|
||||||
_devices = devices;
|
_devices = devices;
|
||||||
_isRememberedDevice = isRememberedDevice;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount() = _devices.size;
|
override fun getItemCount() = _devices.size;
|
||||||
|
@ -24,13 +24,13 @@ class DeviceAdapter : RecyclerView.Adapter<DeviceViewHolder> {
|
||||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): DeviceViewHolder {
|
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): DeviceViewHolder {
|
||||||
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.list_device, viewGroup, false);
|
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.list_device, viewGroup, false);
|
||||||
val holder = DeviceViewHolder(view);
|
val holder = DeviceViewHolder(view);
|
||||||
holder.setIsRememberedDevice(_isRememberedDevice);
|
holder.onPin.subscribe { d -> onPin.emit(d); };
|
||||||
holder.onRemove.subscribe { d -> onRemove.emit(d); };
|
|
||||||
holder.onConnect.subscribe { d -> onConnect.emit(d); }
|
holder.onConnect.subscribe { d -> onConnect.emit(d); }
|
||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(viewHolder: DeviceViewHolder, position: Int) {
|
override fun onBindViewHolder(viewHolder: DeviceViewHolder, position: Int) {
|
||||||
viewHolder.bind(_devices[position]);
|
val p = _devices[position];
|
||||||
|
viewHolder.bind(p.castingDevice, p.isOnlineDevice, p.isPinnedDevice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package com.futo.platformplayer.views.adapters
|
||||||
|
|
||||||
import android.graphics.drawable.Animatable
|
import android.graphics.drawable.Animatable
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.FrameLayout
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
import com.futo.platformplayer.R
|
import com.futo.platformplayer.R
|
||||||
import com.futo.platformplayer.casting.AirPlayCastingDevice
|
import com.futo.platformplayer.casting.AirPlayCastingDevice
|
||||||
|
@ -14,70 +16,62 @@ import com.futo.platformplayer.casting.ChromecastCastingDevice
|
||||||
import com.futo.platformplayer.casting.FCastCastingDevice
|
import com.futo.platformplayer.casting.FCastCastingDevice
|
||||||
import com.futo.platformplayer.casting.StateCasting
|
import com.futo.platformplayer.casting.StateCasting
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
import com.futo.platformplayer.constructs.Event2
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
|
||||||
class DeviceViewHolder : ViewHolder {
|
class DeviceViewHolder : ViewHolder {
|
||||||
|
private val _layoutDevice: FrameLayout;
|
||||||
private val _imageDevice: ImageView;
|
private val _imageDevice: ImageView;
|
||||||
private val _textName: TextView;
|
private val _textName: TextView;
|
||||||
private val _textType: TextView;
|
private val _textType: TextView;
|
||||||
private val _textNotReady: TextView;
|
private val _textNotReady: TextView;
|
||||||
private val _buttonDisconnect: LinearLayout;
|
|
||||||
private val _buttonConnect: LinearLayout;
|
|
||||||
private val _buttonRemove: LinearLayout;
|
|
||||||
private val _imageLoader: ImageView;
|
private val _imageLoader: ImageView;
|
||||||
|
private val _imageOnline: ImageView;
|
||||||
|
private val _root: ConstraintLayout;
|
||||||
private var _animatableLoader: Animatable? = null;
|
private var _animatableLoader: Animatable? = null;
|
||||||
private var _isRememberedDevice: Boolean = false;
|
private var _imagePin: ImageView;
|
||||||
|
|
||||||
var device: CastingDevice? = null
|
var device: CastingDevice? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var onRemove = Event1<CastingDevice>();
|
var onPin = Event1<CastingDevice>();
|
||||||
val onConnect = Event1<CastingDevice>();
|
val onConnect = Event1<CastingDevice>();
|
||||||
|
|
||||||
constructor(view: View) : super(view) {
|
constructor(view: View) : super(view) {
|
||||||
|
_root = view.findViewById(R.id.layout_root);
|
||||||
|
_layoutDevice = view.findViewById(R.id.layout_device);
|
||||||
_imageDevice = view.findViewById(R.id.image_device);
|
_imageDevice = view.findViewById(R.id.image_device);
|
||||||
_textName = view.findViewById(R.id.text_name);
|
_textName = view.findViewById(R.id.text_name);
|
||||||
_textType = view.findViewById(R.id.text_type);
|
_textType = view.findViewById(R.id.text_type);
|
||||||
_textNotReady = view.findViewById(R.id.text_not_ready);
|
_textNotReady = view.findViewById(R.id.text_not_ready);
|
||||||
_buttonDisconnect = view.findViewById(R.id.button_disconnect);
|
|
||||||
_buttonConnect = view.findViewById(R.id.button_connect);
|
|
||||||
_buttonRemove = view.findViewById(R.id.button_remove);
|
|
||||||
_imageLoader = view.findViewById(R.id.image_loader);
|
_imageLoader = view.findViewById(R.id.image_loader);
|
||||||
|
_imageOnline = view.findViewById(R.id.image_online);
|
||||||
|
_imagePin = view.findViewById(R.id.image_pin);
|
||||||
|
|
||||||
val d = _imageLoader.drawable;
|
val d = _imageLoader.drawable;
|
||||||
if (d is Animatable) {
|
if (d is Animatable) {
|
||||||
_animatableLoader = d;
|
_animatableLoader = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
_buttonDisconnect.setOnClickListener {
|
val connect = {
|
||||||
StateCasting.instance.activeDevice?.stopCasting();
|
device?.let { dev ->
|
||||||
updateButton();
|
StateCasting.instance.activeDevice?.stopCasting();
|
||||||
};
|
StateCasting.instance.connectDevice(dev);
|
||||||
|
onConnect.emit(dev);
|
||||||
_buttonConnect.setOnClickListener {
|
}
|
||||||
val dev = device ?: return@setOnClickListener;
|
|
||||||
StateCasting.instance.activeDevice?.stopCasting();
|
|
||||||
StateCasting.instance.connectDevice(dev);
|
|
||||||
onConnect.emit(dev);
|
|
||||||
};
|
|
||||||
|
|
||||||
_buttonRemove.setOnClickListener {
|
|
||||||
val dev = device ?: return@setOnClickListener;
|
|
||||||
onRemove.emit(dev);
|
|
||||||
};
|
|
||||||
|
|
||||||
StateCasting.instance.onActiveDeviceConnectionStateChanged.subscribe(this) { _, _ ->
|
|
||||||
updateButton();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsRememberedDevice(false);
|
_textName.setOnClickListener { connect() };
|
||||||
|
_textType.setOnClickListener { connect() };
|
||||||
|
_layoutDevice.setOnClickListener { connect() };
|
||||||
|
|
||||||
|
_imagePin.setOnClickListener {
|
||||||
|
val dev = device ?: return@setOnClickListener;
|
||||||
|
onPin.emit(dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setIsRememberedDevice(isRememberedDevice: Boolean) {
|
fun bind(d: CastingDevice, isOnlineDevice: Boolean, isPinnedDevice: Boolean) {
|
||||||
_isRememberedDevice = isRememberedDevice;
|
|
||||||
_buttonRemove.visibility = if (isRememberedDevice) View.VISIBLE else View.GONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fun bind(d: CastingDevice) {
|
|
||||||
if (d is ChromecastCastingDevice) {
|
if (d is ChromecastCastingDevice) {
|
||||||
_imageDevice.setImageResource(R.drawable.ic_chromecast);
|
_imageDevice.setImageResource(R.drawable.ic_chromecast);
|
||||||
_textType.text = "Chromecast";
|
_textType.text = "Chromecast";
|
||||||
|
@ -90,54 +84,47 @@ class DeviceViewHolder : ViewHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
_textName.text = d.name;
|
_textName.text = d.name;
|
||||||
device = d;
|
_imageOnline.visibility = if (isOnlineDevice) View.VISIBLE else View.GONE
|
||||||
updateButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateButton() {
|
|
||||||
val d = device ?: return;
|
|
||||||
|
|
||||||
if (!d.isReady) {
|
if (!d.isReady) {
|
||||||
_buttonConnect.visibility = View.GONE;
|
|
||||||
_buttonDisconnect.visibility = View.GONE;
|
|
||||||
_imageLoader.visibility = View.GONE;
|
_imageLoader.visibility = View.GONE;
|
||||||
_textNotReady.visibility = View.VISIBLE;
|
_textNotReady.visibility = View.VISIBLE;
|
||||||
return;
|
_imagePin.visibility = View.GONE;
|
||||||
}
|
|
||||||
|
|
||||||
_textNotReady.visibility = View.GONE;
|
|
||||||
|
|
||||||
val dev = StateCasting.instance.activeDevice;
|
|
||||||
if (dev == d) {
|
|
||||||
if (dev.connectionState == CastConnectionState.CONNECTED) {
|
|
||||||
_buttonConnect.visibility = View.GONE;
|
|
||||||
_buttonDisconnect.visibility = View.VISIBLE;
|
|
||||||
_imageLoader.visibility = View.GONE;
|
|
||||||
_textNotReady.visibility = View.GONE;
|
|
||||||
} else {
|
|
||||||
_buttonConnect.visibility = View.GONE;
|
|
||||||
_buttonDisconnect.visibility = View.VISIBLE;
|
|
||||||
_imageLoader.visibility = View.VISIBLE;
|
|
||||||
_textNotReady.visibility = View.GONE;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (d.isReady) {
|
_textNotReady.visibility = View.GONE;
|
||||||
_buttonConnect.visibility = View.VISIBLE;
|
|
||||||
_buttonDisconnect.visibility = View.GONE;
|
val dev = StateCasting.instance.activeDevice;
|
||||||
_imageLoader.visibility = View.GONE;
|
if (dev == d) {
|
||||||
_textNotReady.visibility = View.GONE;
|
if (dev.connectionState == CastConnectionState.CONNECTED) {
|
||||||
|
_imageLoader.visibility = View.GONE;
|
||||||
|
_textNotReady.visibility = View.GONE;
|
||||||
|
_imagePin.visibility = View.VISIBLE;
|
||||||
|
} else {
|
||||||
|
_imageLoader.visibility = View.VISIBLE;
|
||||||
|
_textNotReady.visibility = View.GONE;
|
||||||
|
_imagePin.visibility = View.VISIBLE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_buttonConnect.visibility = View.GONE;
|
if (d.isReady) {
|
||||||
_buttonDisconnect.visibility = View.GONE;
|
_imageLoader.visibility = View.GONE;
|
||||||
_imageLoader.visibility = View.GONE;
|
_textNotReady.visibility = View.GONE;
|
||||||
_textNotReady.visibility = View.VISIBLE;
|
_imagePin.visibility = View.VISIBLE;
|
||||||
|
} else {
|
||||||
|
_imageLoader.visibility = View.GONE;
|
||||||
|
_textNotReady.visibility = View.VISIBLE;
|
||||||
|
_imagePin.visibility = View.VISIBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_imagePin.setImageResource(if (isPinnedDevice) R.drawable.keep_24px else R.drawable.ic_pin)
|
||||||
|
|
||||||
|
if (_imageLoader.isVisible) {
|
||||||
|
_animatableLoader?.start();
|
||||||
|
} else {
|
||||||
|
_animatableLoader?.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_imageLoader.visibility == View.VISIBLE) {
|
device = d;
|
||||||
_animatableLoader?.start();
|
|
||||||
} else {
|
|
||||||
_animatableLoader?.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
9
app/src/main/res/drawable/keep_24px.xml
Normal file
9
app/src/main/res/drawable/keep_24px.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M600,496.92L663.08,560L663.08,600L500,600L500,800L480,820L460,800L460,600L296.92,600L296.92,560L360,496.92L360,200L320,200L320,160L640,160L640,200L600,200L600,496.92Z"/>
|
||||||
|
</vector>
|
|
@ -11,25 +11,48 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="12dp">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/text_devices"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/discovered_devices"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="20dp"
|
|
||||||
android:textSize="14dp"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:fontFamily="@font/inter_regular" />
|
|
||||||
|
|
||||||
<ImageView
|
<TextView
|
||||||
android:id="@+id/image_loader"
|
android:id="@+id/text_devices"
|
||||||
android:layout_width="22dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="22dp"
|
android:layout_height="wrap_content"
|
||||||
android:scaleType="fitCenter"
|
android:text="@string/discovered_devices"
|
||||||
app:srcCompat="@drawable/ic_loader_animated"
|
android:layout_marginStart="20dp"
|
||||||
android:layout_marginStart="5dp"/>
|
android:textSize="14dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:fontFamily="@font/inter_regular" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/available_devices"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:textSize="11dp"
|
||||||
|
android:textColor="@color/gray_ac"
|
||||||
|
android:fontFamily="@font/inter_medium" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_loader"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:srcCompat="@drawable/ic_loader_animated"
|
||||||
|
android:layout_marginStart="5dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<Space android:layout_width="0dp"
|
<Space android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -38,7 +61,7 @@
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_close"
|
android:id="@+id/button_close"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/close"
|
android:text="@string/close"
|
||||||
android:textSize="14dp"
|
android:textSize="14dp"
|
||||||
android:fontFamily="@font/inter_regular"
|
android:fontFamily="@font/inter_regular"
|
||||||
|
@ -67,79 +90,102 @@
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_devices"
|
android:id="@+id/recycler_devices"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="100dp"
|
android:layout_height="200dp"
|
||||||
android:layout_marginStart="20dp"
|
android:layout_marginStart="20dp"
|
||||||
android:layout_marginEnd="20dp" />
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="20dp"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:background="@color/gray_ac" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_remembered_devices"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/unable_to_see_the_Device_youre_looking_for_try_add_the_device_manually"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:textSize="9dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textColor="@color/gray_c3"
|
||||||
|
android:maxLines="3"
|
||||||
|
android:fontFamily="@font/inter_light"
|
||||||
|
android:layout_marginTop="12dp"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layout_remembered_devices_header"
|
android:id="@+id/layout_remembered_devices_header"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
<TextView
|
android:layout_marginBottom="12dp"
|
||||||
android:id="@+id/text_remembered_devices"
|
android:layout_marginStart="20dp"
|
||||||
android:layout_width="0dp"
|
android:layout_marginEnd="20dp">
|
||||||
android:layout_weight="3"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/remembered_devices"
|
|
||||||
android:layout_marginStart="20dp"
|
|
||||||
android:layout_marginEnd="20dp"
|
|
||||||
android:textSize="14dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:fontFamily="@font/inter_regular" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/button_scan_qr"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:contentDescription="@string/cd_button_scan_qr"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
app:srcCompat="@drawable/ic_qr"
|
|
||||||
app:tint="@color/primary" />
|
|
||||||
|
|
||||||
<Space android:layout_width="0dp"
|
<Space android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<ImageButton
|
<LinearLayout
|
||||||
android:id="@+id/button_add"
|
android:id="@+id/button_add"
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:contentDescription="@string/cd_button_add"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
app:srcCompat="@drawable/ic_add"
|
|
||||||
app:tint="@color/primary"
|
|
||||||
android:layout_marginEnd="20dp"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/layout_remembered_devices"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_no_devices_remembered"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="10dp"
|
android:orientation="horizontal"
|
||||||
android:text="@string/there_are_no_remembered_devices"
|
android:background="@drawable/background_border_2e_round_6dp"
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:layout_marginBottom="20dp"
|
|
||||||
android:layout_marginStart="20dp"
|
|
||||||
android:layout_marginEnd="20dp"
|
android:layout_marginEnd="20dp"
|
||||||
android:textColor="@color/gray_e0" />
|
android:gravity="center">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<ImageView
|
||||||
android:id="@+id/recycler_remembered_devices"
|
android:layout_width="22dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="22dp"
|
||||||
android:layout_height="100dp"
|
app:srcCompat="@drawable/ic_add"
|
||||||
android:layout_marginStart="20dp"
|
android:layout_marginStart="8dp"/>
|
||||||
android:layout_marginEnd="20dp" />
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/add_manually"
|
||||||
|
android:textSize="12dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:fontFamily="@font/inter_medium"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="12dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/button_qr"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:background="@drawable/background_border_2e_round_6dp"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="22dp"
|
||||||
|
android:layout_height="22dp"
|
||||||
|
app:srcCompat="@drawable/ic_qr"
|
||||||
|
android:layout_marginStart="8dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/scan_qr"
|
||||||
|
android:textSize="12dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:fontFamily="@font/inter_medium"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="12dp" />
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -4,18 +4,34 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:clickable="true">
|
android:clickable="true"
|
||||||
|
android:id="@+id/layout_root">
|
||||||
|
|
||||||
<ImageView
|
<FrameLayout
|
||||||
android:id="@+id/image_device"
|
android:id="@+id/layout_device"
|
||||||
android:layout_width="25dp"
|
android:layout_width="25dp"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:contentDescription="@string/cd_image_device"
|
|
||||||
app:srcCompat="@drawable/ic_chromecast"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_device"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:contentDescription="@string/cd_image_device"
|
||||||
|
app:srcCompat="@drawable/ic_chromecast"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_online"
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_gravity="end|top"
|
||||||
|
android:contentDescription="@string/cd_image_device"
|
||||||
|
app:srcCompat="@drawable/ic_online"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_name"
|
android:id="@+id/text_name"
|
||||||
|
@ -31,8 +47,8 @@
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:includeFontPadding="false"
|
android:includeFontPadding="false"
|
||||||
app:layout_constraintTop_toTopOf="@id/image_device"
|
app:layout_constraintTop_toTopOf="@id/layout_device"
|
||||||
app:layout_constraintLeft_toRightOf="@id/image_device"
|
app:layout_constraintLeft_toRightOf="@id/layout_device"
|
||||||
app:layout_constraintRight_toLeftOf="@id/layout_button" />
|
app:layout_constraintRight_toLeftOf="@id/layout_button" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -43,12 +59,12 @@
|
||||||
tools:text="Chromecast"
|
tools:text="Chromecast"
|
||||||
android:textSize="10dp"
|
android:textSize="10dp"
|
||||||
android:fontFamily="@font/inter_extra_light"
|
android:fontFamily="@font/inter_extra_light"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/gray_ac"
|
||||||
android:includeFontPadding="false"
|
android:includeFontPadding="false"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/text_name"
|
app:layout_constraintTop_toBottomOf="@id/text_name"
|
||||||
app:layout_constraintLeft_toRightOf="@id/image_device"
|
app:layout_constraintLeft_toRightOf="@id/layout_device"
|
||||||
app:layout_constraintRight_toLeftOf="@id/layout_button" />
|
app:layout_constraintRight_toLeftOf="@id/layout_button" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -68,74 +84,15 @@
|
||||||
app:srcCompat="@drawable/ic_loader_animated"
|
app:srcCompat="@drawable/ic_loader_animated"
|
||||||
android:layout_marginEnd="8dp"/>
|
android:layout_marginEnd="8dp"/>
|
||||||
|
|
||||||
<LinearLayout
|
<ImageView
|
||||||
|
android:id="@+id/image_pin"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="25dp"
|
||||||
android:orientation="horizontal"
|
android:contentDescription="@string/cd_image_loader"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:srcCompat="@drawable/ic_pin"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:layout_marginEnd="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent">
|
android:scaleType="fitEnd"
|
||||||
|
android:paddingStart="10dp" />
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/button_remove"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/background_button_accent"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingBottom="4dp"
|
|
||||||
android:layout_marginEnd="7dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12dp"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:fontFamily="@font/inter_light"
|
|
||||||
android:text="@string/remove" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/button_disconnect"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/background_button_accent"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingBottom="4dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12dp"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:fontFamily="@font/inter_light"
|
|
||||||
android:text="@string/stop" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/button_connect"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/background_button_primary"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingBottom="4dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12dp"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:fontFamily="@font/inter_light"
|
|
||||||
android:text="@string/start" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_not_ready"
|
android:id="@+id/text_not_ready"
|
||||||
|
|
|
@ -194,7 +194,9 @@
|
||||||
<string name="ip">IP</string>
|
<string name="ip">IP</string>
|
||||||
<string name="port">Port</string>
|
<string name="port">Port</string>
|
||||||
<string name="discovered_devices">Discovered Devices</string>
|
<string name="discovered_devices">Discovered Devices</string>
|
||||||
|
<string name="available_devices">Available devices</string>
|
||||||
<string name="remembered_devices">Remembered Devices</string>
|
<string name="remembered_devices">Remembered Devices</string>
|
||||||
|
<string name="unable_to_see_the_Device_youre_looking_for_try_add_the_device_manually">Unable to see the device you\'re looking for? Try to add the device manually.</string>
|
||||||
<string name="there_are_no_remembered_devices">There are no remembered devices</string>
|
<string name="there_are_no_remembered_devices">There are no remembered devices</string>
|
||||||
<string name="connected_to">Connected to</string>
|
<string name="connected_to">Connected to</string>
|
||||||
<string name="volume">Volume</string>
|
<string name="volume">Volume</string>
|
||||||
|
@ -204,6 +206,7 @@
|
||||||
<string name="previous">Previous</string>
|
<string name="previous">Previous</string>
|
||||||
<string name="next">Next</string>
|
<string name="next">Next</string>
|
||||||
<string name="comment">Comment</string>
|
<string name="comment">Comment</string>
|
||||||
|
<string name="add_manually">Add manually</string>
|
||||||
<string name="not_empty_close">Comment is not empty, close anyway?</string>
|
<string name="not_empty_close">Comment is not empty, close anyway?</string>
|
||||||
<string name="str_import">Import</string>
|
<string name="str_import">Import</string>
|
||||||
<string name="my_playlist_name">My Playlist Name</string>
|
<string name="my_playlist_name">My Playlist Name</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue