Skip to content

Commit 5019efe

Browse files
atm1504iamareebjamal
authored andcommitted
feat: Display connected devices (#2276)
* feat: Add ui for display of connected devices * feat: Fetch datas from the server * parsing devices * feat: refine and finalize view of connected devices
1 parent 1e45b15 commit 5019efe

File tree

16 files changed

+266
-6
lines changed

16 files changed

+266
-6
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
package org.fossasia.susi.ai.data.contract
22

33
import org.fossasia.susi.ai.dataclasses.AddDeviceQuery
4+
import org.fossasia.susi.ai.rest.responses.susi.ConnectedDevicesResponse
5+
import retrofit2.Response
46

57
interface IRoomModel {
8+
9+
interface onConnectedDeviceFetchingFinishedListener {
10+
fun onRoomModelSuccess(response: Response<ConnectedDevicesResponse>)
11+
fun onError(throwable: Throwable)
12+
}
13+
614
fun addDeviceToServer(query: AddDeviceQuery)
15+
fun getConnectedDevices(listener: onConnectedDeviceFetchingFinishedListener)
716
}

app/src/main/java/org/fossasia/susi/ai/data/device/RoomModel.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.fossasia.susi.ai.data.device
33
import org.fossasia.susi.ai.data.contract.IRoomModel
44
import org.fossasia.susi.ai.dataclasses.AddDeviceQuery
55
import org.fossasia.susi.ai.rest.ClientBuilder
6+
import org.fossasia.susi.ai.rest.responses.susi.ConnectedDevicesResponse
67
import org.fossasia.susi.ai.rest.responses.susi.GetAddDeviceResponse
78
import retrofit2.Call
89
import retrofit2.Callback
@@ -11,6 +12,7 @@ import timber.log.Timber
1112

1213
class RoomModel : IRoomModel {
1314
private lateinit var addDeviceResponseCall: Call<GetAddDeviceResponse>
15+
private lateinit var connectedDeviceResponseCall: Call<ConnectedDevicesResponse>
1416

1517
override fun addDeviceToServer(query: AddDeviceQuery) {
1618
addDeviceResponseCall = ClientBuilder.addDeviceCall(query)
@@ -25,4 +27,18 @@ class RoomModel : IRoomModel {
2527
}
2628
})
2729
}
30+
31+
override fun getConnectedDevices(listener: IRoomModel.onConnectedDeviceFetchingFinishedListener) {
32+
connectedDeviceResponseCall = ClientBuilder.susiApi.getConnectedDevices
33+
34+
connectedDeviceResponseCall.enqueue(object : Callback<ConnectedDevicesResponse> {
35+
override fun onFailure(call: Call<ConnectedDevicesResponse>, t: Throwable) {
36+
listener.onError(t)
37+
}
38+
39+
override fun onResponse(call: Call<ConnectedDevicesResponse>, response: Response<ConnectedDevicesResponse>) {
40+
listener.onRoomModelSuccess(response)
41+
}
42+
})
43+
}
2844
}

app/src/main/java/org/fossasia/susi/ai/device/DeviceActivity.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.os.Bundle
66
import android.support.v7.app.AppCompatActivity
77
import android.view.MenuItem
88
import org.fossasia.susi.ai.R
9+
import org.fossasia.susi.ai.device.connecteddevices.ConnectedDeviceFragment
910
import org.fossasia.susi.ai.device.deviceconnect.DeviceConnectFragment
1011

1112
/*
@@ -18,6 +19,7 @@ class DeviceActivity : AppCompatActivity() {
1819

1920
private val TAG_DEVICE_CONNECT_FRAGMENT = "DeviceConnectFragment"
2021
private val TAG_DEVICE_DETAILS_FRAGMENT = "DeviceDetailsFragment"
22+
private val TAG_CONNECTED_DEVICE_FRAGMNENT = "ConnectedDeviceFragment"
2123

2224
lateinit var mainWifi: WifiManager
2325

@@ -28,10 +30,17 @@ class DeviceActivity : AppCompatActivity() {
2830

2931
mainWifi = application.getSystemService(Context.WIFI_SERVICE) as WifiManager
3032

31-
val deviceConnectFragment = DeviceConnectFragment()
32-
supportFragmentManager.beginTransaction()
33-
.replace(R.id.fragment_container, deviceConnectFragment, TAG_DEVICE_CONNECT_FRAGMENT)
34-
.commit()
33+
if (intent.getStringExtra("connectTo") == "DeviceConnectFragment") {
34+
val deviceConnectFragment = DeviceConnectFragment()
35+
supportFragmentManager.beginTransaction()
36+
.replace(R.id.fragment_container, deviceConnectFragment, TAG_DEVICE_CONNECT_FRAGMENT)
37+
.commit()
38+
} else {
39+
val connectedDeviceFragment = ConnectedDeviceFragment()
40+
supportFragmentManager.beginTransaction()
41+
.replace(R.id.fragment_container, connectedDeviceFragment, TAG_CONNECTED_DEVICE_FRAGMNENT)
42+
.commit()
43+
}
3544
}
3645

3746
override fun onOptionsItemSelected(item: MenuItem): Boolean {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.fossasia.susi.ai.device.connecteddevices
2+
3+
import android.os.Bundle
4+
import android.support.v4.app.Fragment
5+
import android.support.v7.widget.LinearLayoutManager
6+
import android.support.v7.widget.RecyclerView
7+
import android.view.LayoutInflater
8+
import android.view.View
9+
import android.view.ViewGroup
10+
import kotlinx.android.synthetic.main.fragment_connected_device.deviceStatus
11+
import org.fossasia.susi.ai.R
12+
import org.fossasia.susi.ai.device.connecteddevices.adapters.ConnectedDevicesAdapter
13+
import org.fossasia.susi.ai.device.connecteddevices.contract.IConnectedDevicePresenter
14+
import org.fossasia.susi.ai.device.connecteddevices.contract.IConnectedDeviceView
15+
import org.fossasia.susi.ai.rest.responses.susi.Device
16+
17+
class ConnectedDeviceFragment : Fragment(), IConnectedDeviceView {
18+
19+
private lateinit var connectedDeviceRecyclerView: RecyclerView
20+
private lateinit var connectedDevicePresenter: IConnectedDevicePresenter
21+
private var connectedDevicesAdapter: RecyclerView.Adapter<*>? = null
22+
private val connectedDeviceList: ArrayList<Device> = ArrayList()
23+
24+
override fun onCreate(savedInstanceState: Bundle?) {
25+
super.onCreate(savedInstanceState)
26+
}
27+
28+
override fun onCreateView(
29+
inflater: LayoutInflater,
30+
container: ViewGroup?,
31+
savedInstanceState: Bundle?
32+
): View? {
33+
// Inflate the layout for this fragment
34+
val rootView = inflater.inflate(R.layout.fragment_connected_device, container, false)
35+
connectedDeviceRecyclerView = rootView.findViewById(R.id.connectedDevices)
36+
return rootView
37+
}
38+
39+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
40+
connectedDevicePresenter = ConnectedDevicePresenter(this)
41+
connectedDevicePresenter.onAttach(this)
42+
connectedDevicePresenter.getDevices()
43+
super.onViewCreated(view, savedInstanceState)
44+
}
45+
46+
override fun getConnectedDeviceDetails(deviceResponseMap: Map<String, Device>?) {
47+
48+
deviceResponseMap?.forEach { item ->
49+
connectedDeviceList.add(item.value)
50+
}
51+
52+
if (connectedDeviceList.isNullOrEmpty()) {
53+
deviceStatus.visibility = View.VISIBLE
54+
deviceStatus.text = getString(R.string.connected_device_status)
55+
} else {
56+
deviceStatus.visibility = View.GONE
57+
showDevices()
58+
}
59+
}
60+
61+
fun showDevices() {
62+
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
63+
connectedDeviceRecyclerView.layoutManager = layoutManager
64+
connectedDevicesAdapter = ConnectedDevicesAdapter(connectedDeviceList)
65+
connectedDeviceRecyclerView.adapter = connectedDevicesAdapter
66+
}
67+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.fossasia.susi.ai.device.connecteddevices
2+
3+
import org.fossasia.susi.ai.data.contract.IRoomModel
4+
import org.fossasia.susi.ai.data.device.RoomModel
5+
import org.fossasia.susi.ai.device.connecteddevices.contract.IConnectedDevicePresenter
6+
import org.fossasia.susi.ai.device.connecteddevices.contract.IConnectedDeviceView
7+
import org.fossasia.susi.ai.rest.responses.susi.ConnectedDevicesResponse
8+
import retrofit2.Response
9+
import timber.log.Timber
10+
11+
class ConnectedDevicePresenter(val connectedDeviceFragment: ConnectedDeviceFragment) :
12+
IConnectedDevicePresenter,
13+
IRoomModel.onConnectedDeviceFetchingFinishedListener {
14+
15+
private val roomModel: RoomModel = RoomModel()
16+
private var connectedDeviceView: IConnectedDeviceView? = null
17+
18+
override fun onAttach(connectedDeviceView: IConnectedDeviceView) {
19+
this.connectedDeviceView = connectedDeviceView
20+
}
21+
22+
override fun getDevices() {
23+
roomModel.getConnectedDevices(this)
24+
}
25+
26+
override fun onRoomModelSuccess(response: Response<ConnectedDevicesResponse>) {
27+
Timber.d("Showing list of connected devices")
28+
val deviceResponse = response.body()
29+
val deviceResponseMap = deviceResponse?.devices
30+
connectedDeviceView?.getConnectedDeviceDetails(deviceResponseMap)
31+
}
32+
33+
override fun onError(throwable: Throwable) {
34+
Timber.d("Failed to fetch data about list of available devices")
35+
Timber.d(throwable)
36+
}
37+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.fossasia.susi.ai.device.connecteddevices.adapters
2+
3+
import android.support.v7.widget.RecyclerView
4+
import android.view.LayoutInflater
5+
import android.view.View
6+
import android.view.ViewGroup
7+
import android.widget.TextView
8+
import org.fossasia.susi.ai.R
9+
import org.fossasia.susi.ai.rest.responses.susi.Device
10+
11+
class ConnectedDevicesAdapter(private val connectedDevicesList: ArrayList<Device>) : RecyclerView.Adapter<ConnectedDevicesAdapter.ViewHolder>() {
12+
13+
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
14+
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.device_layout, viewGroup, false)
15+
return ViewHolder(view)
16+
}
17+
18+
override fun getItemCount(): Int {
19+
return connectedDevicesList.size
20+
}
21+
22+
override fun onBindViewHolder(holder: ViewHolder, p1: Int) {
23+
holder.ssid_name.text = connectedDevicesList[p1].name
24+
holder.setup_option.text = connectedDevicesList[p1].room
25+
}
26+
27+
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
28+
internal var ssid_name: TextView
29+
internal var setup_option: TextView
30+
31+
init {
32+
ssid_name = itemView.findViewById(R.id.speakerName)
33+
setup_option = itemView.findViewById(R.id.speakerSetUp)
34+
}
35+
}
36+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.fossasia.susi.ai.device.connecteddevices.contract
2+
3+
interface IConnectedDevicePresenter {
4+
5+
fun onAttach(connectedDeviceView: IConnectedDeviceView)
6+
7+
fun getDevices()
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.fossasia.susi.ai.device.connecteddevices.contract
2+
3+
import org.fossasia.susi.ai.rest.responses.susi.Device
4+
5+
interface IConnectedDeviceView {
6+
7+
fun getConnectedDeviceDetails(deviceResponseMap: Map<String, Device>?)
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.fossasia.susi.ai.rest.responses.susi
2+
3+
data class ConnectedDevicesResponse(
4+
val session: Session? = null,
5+
val settings: Settings? = null,
6+
val devices: Map<String, Device>? = null,
7+
val lastLoginIP: String? = null,
8+
val lastLoginTime: String? = null
9+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.fossasia.susi.ai.rest.responses.susi
2+
3+
import android.os.Parcelable
4+
import kotlinx.android.parcel.Parcelize
5+
6+
@Parcelize
7+
data class Device(
8+
val name: String? = null,
9+
val room: String? = null,
10+
val geolocation: Location? = null
11+
) : Parcelable
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.fossasia.susi.ai.rest.responses.susi
2+
3+
import android.os.Parcelable
4+
import kotlinx.android.parcel.Parcelize
5+
6+
@Parcelize
7+
data class Location(
8+
val latittude: String? = null,
9+
val longitude: String? = null
10+
) : Parcelable

app/src/main/java/org/fossasia/susi/ai/rest/services/SusiService.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import org.fossasia.susi.ai.rest.responses.susi.SkillRatingResponse
1818
import org.fossasia.susi.ai.rest.responses.susi.SusiResponse
1919
import org.fossasia.susi.ai.rest.responses.susi.UserSetting
2020
import org.fossasia.susi.ai.rest.responses.susi.GetAddDeviceResponse
21+
import org.fossasia.susi.ai.rest.responses.susi.ConnectedDevicesResponse
2122

2223
import retrofit2.Call
2324
import retrofit2.http.GET
@@ -181,9 +182,16 @@ interface SusiService {
181182
@GET("/cms/getRatingByUser.json")
182183
fun getRatingByUser(@QueryMap query: Map<String, String>): Call<GetRatingByUserResponse>
183184

185+
/**
186+
* Add and get list of connected
187+
* Susi Smart Speakers
188+
*/
184189
@GET("/aaa/addNewDevice.json")
185190
fun addSusiDevices(@QueryMap query: Map<String, String>): Call<GetAddDeviceResponse>
186191

192+
@get:GET("/aaa/listUserSettings.json")
193+
val getConnectedDevices: Call<ConnectedDevicesResponse>
194+
187195
/**
188196
* Get feedback list from the server
189197
*

app/src/main/java/org/fossasia/susi/ai/skills/settings/ChatSettingsFragment.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ class ChatSettingsFragment : PreferenceFragmentCompat(), ISettingsView {
116116
if (!utilModel.isLoggedIn()) {
117117
displayEmail.title = "Not logged in"
118118
displayEmail.isEnabled = true
119+
deviceName.isEnabled = false
119120
} else {
120121
displayEmail.title = PrefManager.getStringSet(Constant.SAVED_EMAIL)?.iterator()?.next()
121122
displayEmail.isEnabled = false
123+
deviceName.isEnabled = true
122124
}
123125

124126
setLanguage()
@@ -230,6 +232,14 @@ class ChatSettingsFragment : PreferenceFragmentCompat(), ISettingsView {
230232
setupDevice.setOnPreferenceClickListener {
231233

232234
val intent = Intent(activity, DeviceActivity::class.java)
235+
intent.putExtra("connectTo", "DeviceConnectFragment")
236+
startActivity(intent)
237+
true
238+
}
239+
240+
deviceName.setOnPreferenceClickListener {
241+
val intent = Intent(activity, DeviceActivity::class.java)
242+
intent.putExtra("connectTo", "ConnectedDeviceFragment")
233243
startActivity(intent)
234244
true
235245
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:tools="http://schemas.android.com/tools"
3+
android:layout_width="match_parent"
4+
android:layout_height="match_parent"
5+
android:orientation="vertical"
6+
tools:context="org.fossasia.susi.ai.device.connecteddevices.ConnectedDeviceFragment">
7+
8+
<TextView
9+
android:id="@+id/deviceStatus"
10+
android:layout_width="match_parent"
11+
android:layout_height="wrap_content"
12+
android:layout_gravity="center_vertical"
13+
android:gravity="center_vertical"
14+
android:text="@string/connected_device_status"
15+
android:visibility="gone" />
16+
17+
<android.support.v7.widget.RecyclerView
18+
android:id="@+id/connectedDevices"
19+
android:layout_width="match_parent"
20+
android:layout_height="match_parent" />
21+
22+
</LinearLayout>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@
250250
<string name="pref_share_summary">Share the SUSI app with your friends.</string>
251251
<string name="pref_share_title">Share SUSI</string>
252252

253-
<string name="pref_devices_not_connected">No connected device</string>
253+
<string name="pref_devices_not_connected">Connected devices</string>
254254
<string name="settings_devices_setup">Click here to move to device setup screen</string>
255255
<string name="reset">Reset password</string>
256256
<string name="reset_pass_activity">Reset Password</string>
@@ -530,4 +530,5 @@
530530
<string name="device_room_exp">Choose a location for your SUSI smart speaker. This will help name and organize your devcies.</string>
531531
<string name="my_rooms">My Rooms</string>
532532
<string name="create_new_room">Create new</string>
533+
<string name="connected_device_status">No devices have been connected yet.</string>
533534
</resources>

app/src/main/res/xml/pref_settings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@
7878

7979
<PreferenceScreen
8080
android:key="device"
81-
android:selectable="false"
8281
android:summary="Your device will be shown here when it is connected"
8382
android:title="@string/pref_devices_not_connected" />
8483

0 commit comments

Comments
 (0)