-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #52 from OwlAIProject/ethan/android-api
Model objects and API for conversation
- Loading branch information
Showing
9 changed files
with
278 additions
and
24 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
clients/android/app/src/main/java/com/owl/Owl/ApiServiceSingleton.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.owl.Owl | ||
|
||
object ApiServiceSingleton { | ||
val apiService: ConversationApiService by lazy { | ||
ConversationApiService() | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
clients/android/app/src/main/java/com/owl/Owl/ConversationApiService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.owl.Owl | ||
|
||
import com.google.gson.Gson | ||
import com.google.gson.reflect.TypeToken | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.withContext | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
|
||
class ConversationApiService { | ||
|
||
private val client = OkHttpClient() | ||
private val gson = Gson() | ||
|
||
suspend fun fetchConversations(): List<Conversation> = withContext(Dispatchers.IO) { | ||
try { | ||
val request = Request.Builder() | ||
.url("${AppConstants.apiBaseURL}/conversations") | ||
.addHeader("Authorization", "Bearer ${AppConstants.clientToken}") | ||
.build() | ||
|
||
client.newCall(request).execute().use { response -> | ||
if (!response.isSuccessful) throw Exception("Server responded with code $response") | ||
|
||
val responseBody = response.body?.string() ?: throw Exception("Null Response Body") | ||
val conversationsResponse = gson.fromJson(responseBody, ConversationsResponse::class.java) | ||
conversationsResponse.conversations | ||
} | ||
} catch (e: Exception) { | ||
e.printStackTrace() | ||
emptyList<Conversation>() | ||
} | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
clients/android/app/src/main/java/com/owl/Owl/ConversationsScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.owl.Owl | ||
|
||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.PaddingValues | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.lazy.LazyColumn | ||
import androidx.compose.foundation.lazy.items | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.collectAsState | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.text.style.TextOverflow | ||
import androidx.compose.ui.unit.dp | ||
import androidx.lifecycle.viewmodel.compose.viewModel | ||
|
||
@Composable | ||
fun ConversationsScreen(viewModel: ConversationsViewModel = viewModel()) { | ||
val conversations = viewModel.conversations.collectAsState(initial = emptyList()) | ||
|
||
LazyColumn( | ||
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp) | ||
) { | ||
items(conversations.value, key = { it.id }) { conversation -> | ||
ConversationItem(conversation = conversation) | ||
} | ||
} | ||
} | ||
|
||
@Composable | ||
fun ConversationItem(conversation: Conversation) { | ||
Column(modifier = Modifier.padding(vertical = 8.dp)) { | ||
Text( | ||
text = "Start Time: ${conversation.startTime}", | ||
modifier = Modifier.padding(bottom = 4.dp) | ||
) | ||
Text( | ||
text = "State: ${conversation.state}", | ||
modifier = Modifier.padding(bottom = 4.dp) | ||
) | ||
Text( | ||
text = "Summary: ${conversation.shortSummary ?: conversation.summary ?: "No summary"}", | ||
maxLines = 2, | ||
overflow = TextOverflow.Ellipsis | ||
) | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
clients/android/app/src/main/java/com/owl/Owl/ConversationsViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.owl.Owl | ||
|
||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
import kotlinx.coroutines.launch | ||
|
||
class ConversationsViewModel : ViewModel() { | ||
|
||
private val apiService = ApiServiceSingleton.apiService | ||
|
||
private val _conversations = MutableStateFlow<List<Conversation>>(emptyList()) | ||
val conversations = _conversations.asStateFlow() | ||
|
||
init { | ||
fetchConversations() | ||
} | ||
|
||
fun fetchConversations() { | ||
viewModelScope.launch { | ||
_conversations.value = apiService.fetchConversations() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package com.owl.Owl | ||
|
||
import com.google.gson.annotations.SerializedName | ||
import java.util.Date | ||
|
||
data class ConversationsResponse( | ||
@SerializedName("conversations") val conversations: List<Conversation> | ||
) | ||
|
||
enum class ConversationState { | ||
@SerializedName("CAPTURING") CAPTURING, | ||
@SerializedName("PROCESSING") PROCESSING, | ||
@SerializedName("COMPLETED") COMPLETED, | ||
@SerializedName("FAILED_PROCESSING") FAILED_PROCESSING | ||
} | ||
|
||
data class SuggestedLink( | ||
@SerializedName("url") val url: String | ||
) | ||
|
||
data class Conversation( | ||
@SerializedName("id") val id: Int, | ||
@SerializedName("start_time") val startTime: String, | ||
@SerializedName("end_time") val endTime: String? = null, | ||
@SerializedName("conversation_uuid") val conversationUUID: String, | ||
@SerializedName("capture_segment_file") val captureFileSegment: CaptureFileSegment, | ||
@SerializedName("device_type") val deviceType: String, | ||
@SerializedName("summary") val summary: String? = null, | ||
@SerializedName("summarization_model") val summarizationModel: String? = null, | ||
@SerializedName("short_summary") val shortSummary: String? = null, | ||
@SerializedName("state") val state: ConversationState, | ||
@SerializedName("transcriptions") val transcriptions: List<Transcription>, | ||
@SerializedName("primary_location") val primaryLocation: Location? = null, | ||
@SerializedName("suggested_links") val suggestedLinks: List<SuggestedLink>? = null | ||
) | ||
|
||
data class CaptureFile( | ||
@SerializedName("id") val id: Int, | ||
@SerializedName("filepath") val filePath: String, | ||
@SerializedName("start_time") val startTime: String, | ||
@SerializedName("device_type") val deviceType: String | ||
) | ||
|
||
data class CaptureFileSegment( | ||
@SerializedName("id") val id: Int, | ||
@SerializedName("filepath") val filePath: String, | ||
@SerializedName("duration") val duration: Double? = null, | ||
@SerializedName("source_capture") val sourceCapture: CaptureFile | ||
) | ||
|
||
data class Transcription( | ||
@SerializedName("id") val id: Int, | ||
@SerializedName("model") val model: String, | ||
@SerializedName("realtime") val realtime: Boolean, | ||
@SerializedName("transcription_time") val transcriptionTime: Double, | ||
@SerializedName("utterances") val utterances: List<Utterance> | ||
) | ||
|
||
data class Utterance( | ||
@SerializedName("id") val id: Int, | ||
@SerializedName("start") val start: Double? = null, | ||
@SerializedName("end") val end: Double? = null, | ||
@SerializedName("text") val text: String? = null, | ||
@SerializedName("speaker") val speaker: String? = null | ||
) | ||
|
||
data class Word( | ||
@SerializedName("id") val id: Int, | ||
@SerializedName("word") val word: String, | ||
@SerializedName("start") val start: Double? = null, | ||
@SerializedName("end") val end: Double? = null, | ||
@SerializedName("score") val score: Double? = null, | ||
@SerializedName("speaker") val speaker: String? = null, | ||
@SerializedName("utterance_id") val utteranceId: Int? = null | ||
) | ||
|
||
data class Location( | ||
@SerializedName("id") val id: Int? = null, | ||
@SerializedName("latitude") val latitude: Double, | ||
@SerializedName("longitude") val longitude: Double, | ||
@SerializedName("address") val address: String? = null, | ||
@SerializedName("capture_uuid") val captureUUID: String? = null | ||
) | ||
|
||
data class Capture( | ||
@SerializedName("capture_uuid") val captureUUID: String, | ||
@SerializedName("device_name") val deviceName: String, | ||
@SerializedName("last_disconnect_time") var lastDisconnectTime: String? = null, | ||
@SerializedName("last_connect_time") var lastConnectTime: String? = null | ||
) |