Commit ·
bcaee17
1
Parent(s): 4c99672
feature(#56): complete the functionality to schedule an alarm
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- Android/app/src/main/AndroidManifest.xml +8 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/RisingApplication.kt +1 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/local/dao/ContactDao.kt +4 -4
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/local/dao/ImageDao.kt +4 -4
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/ContactModel.kt +0 -8
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/HelpPromptModel.kt +0 -8
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{AlarmModel.kt → chat/AlarmModel.kt} +1 -1
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{ChatMessageModel.kt → chat/ChatMessageModel.kt} +1 -1
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/chat/ContactModel.kt +8 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{HelpCommandModel.kt → chat/HelpCommandModel.kt} +1 -1
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/chat/HelpPromptModel.kt +22 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{ImageModel.kt → chat/ImageModel.kt} +1 -1
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/chatwidgetprops/ScheduleAlarmProps.kt +46 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/common/Time.kt +7 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/ApiClient.kt +8 -4
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/ApiService.kt +11 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/requests/ImageRelatednessApiRequest.kt +9 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/requests/TrainContactsApiRequest.kt +9 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/requests/TrainImageApiRequest.kt +9 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/ApiResponse.kt +0 -5
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/EmptyResultApiResponse.kt +7 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/Result.kt +9 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/TrainImageApiResponse.kt +12 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/repository/FirebaseRepository.kt +41 -2
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/repository/RemoteRepository.kt +85 -9
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/repository/RoomRepository.kt +8 -8
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/adapters/ChatMainAdapter.kt +106 -37
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/fragments/ChatMainFragment.kt +183 -42
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/interfaces/ChatMessageInterface.kt +2 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/interfaces/OnHideListener.kt +5 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/SendSmsWidget.kt +4 -8
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/alarm/DayOfWeekItem.kt +54 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/alarm/ScheduleAlarmWidget.kt +110 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/contact/ContactDetailWidget.kt +15 -13
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/contact/SearchContactWidget.kt +7 -5
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/helpprompt/HelpPromptWidget.kt +4 -2
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/toolbar/ChatToolsWidget.kt +1 -1
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/viewmodel/ChatViewModel.kt +173 -26
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/Constants.kt +12 -1
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/CallbackTypes.kt +6 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/Converter.kt +13 -3
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/AlarmHelper.kt +65 -25
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/AlarmReceiver.kt +13 -0
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/CommandHelper.kt +2 -6
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/ContactHelper.kt +92 -4
- Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/ImageHelper.kt +15 -2
- Android/app/src/main/res/drawable/bg_circle_button_schedule_alarm_day.xml +6 -0
- Android/app/src/main/res/drawable/bg_circle_button_schedule_alarm_day_selected.xml +6 -0
- Android/app/src/main/res/drawable/bg_item_error_message.xml +7 -0
- Android/app/src/main/res/layout/item_container_chat_widget.xml +12 -0
Android/app/src/main/AndroidManifest.xml
CHANGED
|
@@ -9,6 +9,9 @@
|
|
| 9 |
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
|
| 10 |
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
| 11 |
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
|
|
|
|
|
|
|
|
| 12 |
<uses-permission
|
| 13 |
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
| 14 |
android:maxSdkVersion="32" />
|
|
@@ -48,6 +51,11 @@
|
|
| 48 |
<category android:name="android.intent.category.LAUNCHER" />
|
| 49 |
</intent-filter>
|
| 50 |
</activity>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
</application>
|
| 52 |
|
| 53 |
</manifest>
|
|
|
|
| 9 |
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
|
| 10 |
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
| 11 |
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
| 12 |
+
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
| 13 |
+
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
| 14 |
+
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
| 15 |
<uses-permission
|
| 16 |
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
| 17 |
android:maxSdkVersion="32" />
|
|
|
|
| 51 |
<category android:name="android.intent.category.LAUNCHER" />
|
| 52 |
</intent-filter>
|
| 53 |
</activity>
|
| 54 |
+
|
| 55 |
+
<receiver
|
| 56 |
+
android:name=".utils.helpers.chat.AlarmReceiver"
|
| 57 |
+
android:enabled="true"
|
| 58 |
+
android:exported="true" />
|
| 59 |
</application>
|
| 60 |
|
| 61 |
</manifest>
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/RisingApplication.kt
CHANGED
|
@@ -3,6 +3,7 @@ package com.matthaigh27.chatgptwrapper
|
|
| 3 |
import android.annotation.SuppressLint
|
| 4 |
import android.app.Application
|
| 5 |
import android.provider.Settings
|
|
|
|
| 6 |
import com.google.android.gms.tasks.OnCompleteListener
|
| 7 |
import com.google.firebase.messaging.FirebaseMessaging
|
| 8 |
|
|
|
|
| 3 |
import android.annotation.SuppressLint
|
| 4 |
import android.app.Application
|
| 5 |
import android.provider.Settings
|
| 6 |
+
import android.util.Log
|
| 7 |
import com.google.android.gms.tasks.OnCompleteListener
|
| 8 |
import com.google.firebase.messaging.FirebaseMessaging
|
| 9 |
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/local/dao/ContactDao.kt
CHANGED
|
@@ -7,14 +7,14 @@ import com.matthaigh27.chatgptwrapper.data.local.entity.ContactEntity
|
|
| 7 |
@Dao
|
| 8 |
interface ContactDao {
|
| 9 |
@Insert
|
| 10 |
-
fun insert(contact: ContactEntity)
|
| 11 |
|
| 12 |
@Update
|
| 13 |
-
fun update(contact: ContactEntity)
|
| 14 |
|
| 15 |
@Delete
|
| 16 |
-
fun delete(contact: ContactEntity)
|
| 17 |
|
| 18 |
@Query("SELECT * FROM contacts")
|
| 19 |
-
fun getAllData(): List<ContactEntity>
|
| 20 |
}
|
|
|
|
| 7 |
@Dao
|
| 8 |
interface ContactDao {
|
| 9 |
@Insert
|
| 10 |
+
suspend fun insert(contact: ContactEntity)
|
| 11 |
|
| 12 |
@Update
|
| 13 |
+
suspend fun update(contact: ContactEntity)
|
| 14 |
|
| 15 |
@Delete
|
| 16 |
+
suspend fun delete(contact: ContactEntity)
|
| 17 |
|
| 18 |
@Query("SELECT * FROM contacts")
|
| 19 |
+
suspend fun getAllData(): List<ContactEntity>
|
| 20 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/local/dao/ImageDao.kt
CHANGED
|
@@ -7,14 +7,14 @@ import com.matthaigh27.chatgptwrapper.data.local.entity.ImageEntity
|
|
| 7 |
@Dao
|
| 8 |
interface ImageDao {
|
| 9 |
@Insert
|
| 10 |
-
fun insert(image: ImageEntity)
|
| 11 |
|
| 12 |
@Update
|
| 13 |
-
fun update(image: ImageEntity)
|
| 14 |
|
| 15 |
@Delete
|
| 16 |
-
fun delete(image: ImageEntity)
|
| 17 |
|
| 18 |
@Query("SELECT * FROM images")
|
| 19 |
-
fun getAllData(): List<ImageEntity>
|
| 20 |
}
|
|
|
|
| 7 |
@Dao
|
| 8 |
interface ImageDao {
|
| 9 |
@Insert
|
| 10 |
+
suspend fun insert(image: ImageEntity)
|
| 11 |
|
| 12 |
@Update
|
| 13 |
+
suspend fun update(image: ImageEntity)
|
| 14 |
|
| 15 |
@Delete
|
| 16 |
+
suspend fun delete(image: ImageEntity)
|
| 17 |
|
| 18 |
@Query("SELECT * FROM images")
|
| 19 |
+
suspend fun getAllData(): List<ImageEntity>
|
| 20 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/ContactModel.kt
DELETED
|
@@ -1,8 +0,0 @@
|
|
| 1 |
-
package com.matthaigh27.chatgptwrapper.data.models
|
| 2 |
-
|
| 3 |
-
data class ContactModel(
|
| 4 |
-
var id: String = "",
|
| 5 |
-
var name: String = "",
|
| 6 |
-
var phoneList: ArrayList<String> = ArrayList(),
|
| 7 |
-
var status: String = ""
|
| 8 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/HelpPromptModel.kt
DELETED
|
@@ -1,8 +0,0 @@
|
|
| 1 |
-
package com.matthaigh27.chatgptwrapper.data.models
|
| 2 |
-
|
| 3 |
-
data class HelpPromptModel(
|
| 4 |
-
var name: String = "",
|
| 5 |
-
var description: String = "",
|
| 6 |
-
var prompt: String = "",
|
| 7 |
-
var tags: ArrayList<String> = ArrayList()
|
| 8 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{AlarmModel.kt → chat/AlarmModel.kt}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
-
package com.matthaigh27.chatgptwrapper.data.models
|
| 2 |
|
| 3 |
data class AlarmModel(val id: Int, val time: Long, val enabled: Boolean, val label: String)
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.chat
|
| 2 |
|
| 3 |
data class AlarmModel(val id: Int, val time: Long, val enabled: Boolean, val label: String)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{ChatMessageModel.kt → chat/ChatMessageModel.kt}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
package com.matthaigh27.chatgptwrapper.data.models
|
| 2 |
|
| 3 |
import com.google.gson.JsonElement
|
| 4 |
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.chat
|
| 2 |
|
| 3 |
import com.google.gson.JsonElement
|
| 4 |
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/chat/ContactModel.kt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.chat
|
| 2 |
+
|
| 3 |
+
data class ContactModel(
|
| 4 |
+
var contactId: String = String(),
|
| 5 |
+
var displayName: String = String(),
|
| 6 |
+
var phoneNumbers: ArrayList<String> = ArrayList(),
|
| 7 |
+
var status: String = String()
|
| 8 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{HelpCommandModel.kt → chat/HelpCommandModel.kt}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
package com.matthaigh27.chatgptwrapper.data.models
|
| 2 |
|
| 3 |
data class HelpCommandModel (
|
| 4 |
var main: String? = null,
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.chat
|
| 2 |
|
| 3 |
data class HelpCommandModel (
|
| 4 |
var main: String? = null,
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/chat/HelpPromptModel.kt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.chat
|
| 2 |
+
|
| 3 |
+
import com.google.gson.Gson
|
| 4 |
+
|
| 5 |
+
data class HelpPromptModel(
|
| 6 |
+
var name: String = "",
|
| 7 |
+
var description: String = "",
|
| 8 |
+
var prompt: String = "",
|
| 9 |
+
var tags: ArrayList<String> = ArrayList()
|
| 10 |
+
) {
|
| 11 |
+
override fun toString(): String {
|
| 12 |
+
val gson = Gson()
|
| 13 |
+
return gson.toJson(this)
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
companion object {
|
| 17 |
+
fun init(string: String): HelpPromptModel {
|
| 18 |
+
val gson = Gson()
|
| 19 |
+
return gson.fromJson(string, HelpPromptModel::class.java)
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/{ImageModel.kt → chat/ImageModel.kt}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
package com.matthaigh27.chatgptwrapper.data.models
|
| 2 |
|
| 3 |
import android.net.Uri
|
| 4 |
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.chat
|
| 2 |
|
| 3 |
import android.net.Uri
|
| 4 |
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/chatwidgetprops/ScheduleAlarmProps.kt
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.chatwidgetprops
|
| 2 |
+
|
| 3 |
+
import com.google.gson.Gson
|
| 4 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpPromptModel
|
| 5 |
+
import com.matthaigh27.chatgptwrapper.data.models.common.Time
|
| 6 |
+
|
| 7 |
+
data class ScheduleAlarmProps(
|
| 8 |
+
val time: Time? = null,
|
| 9 |
+
val label: String? = null,
|
| 10 |
+
val repeat: BooleanArray? = null
|
| 11 |
+
) {
|
| 12 |
+
override fun equals(other: Any?): Boolean {
|
| 13 |
+
if (this === other) return true
|
| 14 |
+
if (javaClass != other?.javaClass) return false
|
| 15 |
+
|
| 16 |
+
other as ScheduleAlarmProps
|
| 17 |
+
|
| 18 |
+
if (time != other.time) return false
|
| 19 |
+
if (repeat != null) {
|
| 20 |
+
if (other.repeat == null) return false
|
| 21 |
+
if (!repeat.contentEquals(other.repeat)) return false
|
| 22 |
+
} else if (other.repeat != null) return false
|
| 23 |
+
if (label != other.label) return false
|
| 24 |
+
|
| 25 |
+
return true
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
override fun hashCode(): Int {
|
| 29 |
+
var result = time?.hashCode() ?: 0
|
| 30 |
+
result = 31 * result + (repeat?.contentHashCode() ?: 0)
|
| 31 |
+
result = 31 * result + (label?.hashCode() ?: 0)
|
| 32 |
+
return result
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
override fun toString(): String {
|
| 36 |
+
val gson = Gson()
|
| 37 |
+
return gson.toJson(this)
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
companion object {
|
| 41 |
+
fun init(string: String): ScheduleAlarmProps {
|
| 42 |
+
val gson = Gson()
|
| 43 |
+
return gson.fromJson(string, ScheduleAlarmProps::class.java)
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/models/common/Time.kt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.models.common
|
| 2 |
+
|
| 3 |
+
data class Time (
|
| 4 |
+
val hour:Int,
|
| 5 |
+
val minute:Int,
|
| 6 |
+
val second:Int,
|
| 7 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/ApiClient.kt
CHANGED
|
@@ -1,6 +1,10 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.remote
|
| 2 |
|
| 3 |
import com.matthaigh27.chatgptwrapper.utils.Constants.API_BASE_URL
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
import okhttp3.OkHttpClient
|
| 5 |
import okhttp3.logging.HttpLoggingInterceptor
|
| 6 |
import retrofit2.Retrofit
|
|
@@ -9,10 +13,10 @@ import java.util.concurrent.TimeUnit
|
|
| 9 |
|
| 10 |
object ApiClient {
|
| 11 |
private val client = OkHttpClient.Builder()
|
| 12 |
-
.callTimeout(
|
| 13 |
-
.connectTimeout(
|
| 14 |
-
.readTimeout(
|
| 15 |
-
.writeTimeout(
|
| 16 |
.build()
|
| 17 |
|
| 18 |
private val retrofit = Retrofit.Builder()
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.remote
|
| 2 |
|
| 3 |
import com.matthaigh27.chatgptwrapper.utils.Constants.API_BASE_URL
|
| 4 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TIME_OUT_CALL
|
| 5 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TIME_OUT_CONNECT
|
| 6 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TIME_OUT_READ
|
| 7 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TIME_OUT_WRITE
|
| 8 |
import okhttp3.OkHttpClient
|
| 9 |
import okhttp3.logging.HttpLoggingInterceptor
|
| 10 |
import retrofit2.Retrofit
|
|
|
|
| 13 |
|
| 14 |
object ApiClient {
|
| 15 |
private val client = OkHttpClient.Builder()
|
| 16 |
+
.callTimeout(TIME_OUT_CALL, TimeUnit.SECONDS)
|
| 17 |
+
.connectTimeout(TIME_OUT_CONNECT, TimeUnit.SECONDS)
|
| 18 |
+
.readTimeout(TIME_OUT_READ, TimeUnit.SECONDS)
|
| 19 |
+
.writeTimeout(TIME_OUT_WRITE, TimeUnit.SECONDS)
|
| 20 |
.build()
|
| 21 |
|
| 22 |
private val retrofit = Retrofit.Builder()
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/ApiService.kt
CHANGED
|
@@ -1,8 +1,13 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.remote
|
| 2 |
|
| 3 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.BaseApiRequest
|
|
|
|
| 4 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.NotificationApiRequest
|
|
|
|
|
|
|
| 5 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
|
|
|
|
|
|
| 6 |
import retrofit2.Call
|
| 7 |
import retrofit2.http.Body
|
| 8 |
import retrofit2.http.POST
|
|
@@ -12,4 +17,10 @@ interface ApiService {
|
|
| 12 |
fun getAllHelpCommands(@Body request: BaseApiRequest) : Call<ApiResponse>
|
| 13 |
@POST("sendNotification")
|
| 14 |
fun sendNotification(@Body request: NotificationApiRequest) : Call<ApiResponse>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.remote
|
| 2 |
|
| 3 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.BaseApiRequest
|
| 4 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.ImageRelatednessApiRequest
|
| 5 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.NotificationApiRequest
|
| 6 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.TrainContactsApiRequest
|
| 7 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.TrainImageApiRequest
|
| 8 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
| 9 |
+
import com.matthaigh27.chatgptwrapper.data.remote.responses.EmptyResultApiResponse
|
| 10 |
+
import com.matthaigh27.chatgptwrapper.data.remote.responses.TrainImageApiResponse
|
| 11 |
import retrofit2.Call
|
| 12 |
import retrofit2.http.Body
|
| 13 |
import retrofit2.http.POST
|
|
|
|
| 17 |
fun getAllHelpCommands(@Body request: BaseApiRequest) : Call<ApiResponse>
|
| 18 |
@POST("sendNotification")
|
| 19 |
fun sendNotification(@Body request: NotificationApiRequest) : Call<ApiResponse>
|
| 20 |
+
@POST("train/contacts")
|
| 21 |
+
fun trainContacts(@Body request: TrainContactsApiRequest) : Call<EmptyResultApiResponse>
|
| 22 |
+
@POST("image_relatedness")
|
| 23 |
+
fun getImageRelatedness(@Body request: ImageRelatednessApiRequest) : Call<ApiResponse>
|
| 24 |
+
@POST("uploadImage")
|
| 25 |
+
fun trainImage(@Body request: TrainImageApiRequest) : Call<TrainImageApiResponse>
|
| 26 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/requests/ImageRelatednessApiRequest.kt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.remote.requests
|
| 2 |
+
|
| 3 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.common.Keys
|
| 4 |
+
|
| 5 |
+
data class ImageRelatednessApiRequest(
|
| 6 |
+
val image_name: String,
|
| 7 |
+
val message: String,
|
| 8 |
+
val confs: Keys
|
| 9 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/requests/TrainContactsApiRequest.kt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.remote.requests
|
| 2 |
+
|
| 3 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.ContactModel
|
| 4 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.common.Keys
|
| 5 |
+
|
| 6 |
+
data class TrainContactsApiRequest(
|
| 7 |
+
val contacts: ArrayList<ContactModel>,
|
| 8 |
+
val confs: Keys
|
| 9 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/requests/TrainImageApiRequest.kt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.remote.requests
|
| 2 |
+
|
| 3 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.common.Keys
|
| 4 |
+
|
| 5 |
+
data class TrainImageApiRequest(
|
| 6 |
+
val image_name: String,
|
| 7 |
+
val status: String,
|
| 8 |
+
val confs: Keys
|
| 9 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/ApiResponse.kt
CHANGED
|
@@ -8,8 +8,3 @@ data class ApiResponse (
|
|
| 8 |
val result: Result
|
| 9 |
)
|
| 10 |
|
| 11 |
-
data class Result (
|
| 12 |
-
val program: String,
|
| 13 |
-
val content: JsonElement,
|
| 14 |
-
val url: String
|
| 15 |
-
)
|
|
|
|
| 8 |
val result: Result
|
| 9 |
)
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/EmptyResultApiResponse.kt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.remote.responses
|
| 2 |
+
|
| 3 |
+
data class EmptyResultApiResponse(
|
| 4 |
+
val status_code: Int,
|
| 5 |
+
val message: List<String>,
|
| 6 |
+
val result: String
|
| 7 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/Result.kt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.remote.responses
|
| 2 |
+
|
| 3 |
+
import com.google.gson.JsonElement
|
| 4 |
+
|
| 5 |
+
data class Result (
|
| 6 |
+
val program: String,
|
| 7 |
+
val content: JsonElement,
|
| 8 |
+
val url: String
|
| 9 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/remote/responses/TrainImageApiResponse.kt
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.data.remote.responses
|
| 2 |
+
|
| 3 |
+
data class TrainImageApiResponse(
|
| 4 |
+
val status_code: Int,
|
| 5 |
+
val message: List<String>,
|
| 6 |
+
val result: ImageInfo
|
| 7 |
+
)
|
| 8 |
+
|
| 9 |
+
data class ImageInfo(
|
| 10 |
+
val image_name: String,
|
| 11 |
+
val image_text: String
|
| 12 |
+
)
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/repository/FirebaseRepository.kt
CHANGED
|
@@ -1,8 +1,14 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.repository
|
| 2 |
|
| 3 |
import com.google.firebase.storage.FirebaseStorage
|
| 4 |
-
import com.
|
| 5 |
-
import com.matthaigh27.chatgptwrapper.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
object FirebaseRepository {
|
| 8 |
fun downloadImageWithName(
|
|
@@ -20,4 +26,37 @@ object FirebaseRepository {
|
|
| 20 |
}
|
| 21 |
return
|
| 22 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.repository
|
| 2 |
|
| 3 |
import com.google.firebase.storage.FirebaseStorage
|
| 4 |
+
import com.google.protobuf.Empty
|
| 5 |
+
import com.matthaigh27.chatgptwrapper.data.remote.ApiResource
|
| 6 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.OnFailure
|
| 7 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.OnSuccess
|
| 8 |
+
import kotlinx.coroutines.suspendCancellableCoroutine
|
| 9 |
+
import java.util.UUID
|
| 10 |
+
import kotlin.coroutines.resume
|
| 11 |
+
import kotlin.coroutines.suspendCoroutine
|
| 12 |
|
| 13 |
object FirebaseRepository {
|
| 14 |
fun downloadImageWithName(
|
|
|
|
| 26 |
}
|
| 27 |
return
|
| 28 |
}
|
| 29 |
+
|
| 30 |
+
fun uploadImageAsync(
|
| 31 |
+
imageByteArray: ByteArray,
|
| 32 |
+
onSuccess: OnSuccess<String>,
|
| 33 |
+
onFailure: OnFailure<String>
|
| 34 |
+
) {
|
| 35 |
+
val storageRef = FirebaseStorage.getInstance().reference
|
| 36 |
+
val uuid = UUID.randomUUID()
|
| 37 |
+
val imageName = "images/${uuid}"
|
| 38 |
+
val imageRef = storageRef.child(imageName)
|
| 39 |
+
|
| 40 |
+
val uploadTask = imageRef.putBytes(imageByteArray)
|
| 41 |
+
uploadTask.addOnFailureListener {
|
| 42 |
+
onFailure("Fail to upload image to firebase.")
|
| 43 |
+
}.addOnSuccessListener {
|
| 44 |
+
onSuccess("$uuid")
|
| 45 |
+
}
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
suspend fun uploadImage(imageByteArray: ByteArray): String = suspendCoroutine { continuation ->
|
| 49 |
+
val storageRef = FirebaseStorage.getInstance().reference
|
| 50 |
+
val uuid = UUID.randomUUID()
|
| 51 |
+
val imageName = "images/${uuid}"
|
| 52 |
+
val imageRef = storageRef.child(imageName)
|
| 53 |
+
|
| 54 |
+
val uploadTask = imageRef.putBytes(imageByteArray)
|
| 55 |
+
|
| 56 |
+
uploadTask.addOnFailureListener {
|
| 57 |
+
continuation.resume("Error")
|
| 58 |
+
}.addOnSuccessListener {
|
| 59 |
+
continuation.resume("$uuid")
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/repository/RemoteRepository.kt
CHANGED
|
@@ -1,30 +1,37 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.repository
|
| 2 |
|
| 3 |
import com.matthaigh27.chatgptwrapper.data.remote.ApiClient
|
|
|
|
|
|
|
| 4 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.NotificationApiRequest
|
|
|
|
|
|
|
| 5 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
| 6 |
-
import com.matthaigh27.chatgptwrapper.
|
| 7 |
-
import com.matthaigh27.chatgptwrapper.
|
|
|
|
|
|
|
| 8 |
import com.matthaigh27.chatgptwrapper.utils.helpers.network.RequestFactory.buildBaseApiRequest
|
| 9 |
import retrofit2.Call
|
| 10 |
import retrofit2.Callback
|
| 11 |
import retrofit2.Response
|
|
|
|
|
|
|
| 12 |
|
| 13 |
|
| 14 |
object RemoteRepository {
|
| 15 |
private val apiService = ApiClient.apiService
|
| 16 |
|
| 17 |
fun getAllHelpCommands(
|
| 18 |
-
onSuccess: OnSuccess<ApiResponse>,
|
| 19 |
-
onFailure: OnFailure<String>
|
| 20 |
) {
|
| 21 |
val call = apiService.getAllHelpCommands(buildBaseApiRequest())
|
| 22 |
|
| 23 |
call.enqueue(object : Callback<ApiResponse> {
|
| 24 |
override fun onResponse(call: Call<ApiResponse>, response: Response<ApiResponse>) {
|
| 25 |
-
response.body()?.let {
|
| 26 |
-
onSuccess(
|
| 27 |
-
}?: run {
|
| 28 |
onFailure(response.message())
|
| 29 |
}
|
| 30 |
}
|
|
@@ -45,8 +52,77 @@ object RemoteRepository {
|
|
| 45 |
call.enqueue(object : Callback<ApiResponse> {
|
| 46 |
override fun onResponse(call: Call<ApiResponse>, response: Response<ApiResponse>) {
|
| 47 |
response.body()?.let { data ->
|
| 48 |
-
onSuccess(
|
| 49 |
-
}?: run {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
onFailure(response.message())
|
| 51 |
}
|
| 52 |
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.data.repository
|
| 2 |
|
| 3 |
import com.matthaigh27.chatgptwrapper.data.remote.ApiClient
|
| 4 |
+
import com.matthaigh27.chatgptwrapper.data.remote.ApiResource
|
| 5 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.ImageRelatednessApiRequest
|
| 6 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.NotificationApiRequest
|
| 7 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.TrainContactsApiRequest
|
| 8 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.TrainImageApiRequest
|
| 9 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
| 10 |
+
import com.matthaigh27.chatgptwrapper.data.remote.responses.EmptyResultApiResponse
|
| 11 |
+
import com.matthaigh27.chatgptwrapper.data.remote.responses.TrainImageApiResponse
|
| 12 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.OnFailure
|
| 13 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.OnSuccess
|
| 14 |
import com.matthaigh27.chatgptwrapper.utils.helpers.network.RequestFactory.buildBaseApiRequest
|
| 15 |
import retrofit2.Call
|
| 16 |
import retrofit2.Callback
|
| 17 |
import retrofit2.Response
|
| 18 |
+
import kotlin.coroutines.resume
|
| 19 |
+
import kotlin.coroutines.suspendCoroutine
|
| 20 |
|
| 21 |
|
| 22 |
object RemoteRepository {
|
| 23 |
private val apiService = ApiClient.apiService
|
| 24 |
|
| 25 |
fun getAllHelpCommands(
|
| 26 |
+
onSuccess: OnSuccess<ApiResponse>, onFailure: OnFailure<String>
|
|
|
|
| 27 |
) {
|
| 28 |
val call = apiService.getAllHelpCommands(buildBaseApiRequest())
|
| 29 |
|
| 30 |
call.enqueue(object : Callback<ApiResponse> {
|
| 31 |
override fun onResponse(call: Call<ApiResponse>, response: Response<ApiResponse>) {
|
| 32 |
+
response.body()?.let { data ->
|
| 33 |
+
onSuccess(data)
|
| 34 |
+
} ?: run {
|
| 35 |
onFailure(response.message())
|
| 36 |
}
|
| 37 |
}
|
|
|
|
| 52 |
call.enqueue(object : Callback<ApiResponse> {
|
| 53 |
override fun onResponse(call: Call<ApiResponse>, response: Response<ApiResponse>) {
|
| 54 |
response.body()?.let { data ->
|
| 55 |
+
onSuccess(data)
|
| 56 |
+
} ?: run {
|
| 57 |
+
onFailure(response.message())
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
override fun onFailure(call: Call<ApiResponse>, t: Throwable) {
|
| 62 |
+
onFailure(t.message.toString())
|
| 63 |
+
}
|
| 64 |
+
})
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
fun trainContacts(
|
| 68 |
+
request: TrainContactsApiRequest,
|
| 69 |
+
onSuccess: OnSuccess<EmptyResultApiResponse>,
|
| 70 |
+
onFailure: OnFailure<String>
|
| 71 |
+
) {
|
| 72 |
+
val call = apiService.trainContacts(request)
|
| 73 |
+
|
| 74 |
+
call.enqueue(object : Callback<EmptyResultApiResponse> {
|
| 75 |
+
override fun onResponse(
|
| 76 |
+
call: Call<EmptyResultApiResponse>, response: Response<EmptyResultApiResponse>
|
| 77 |
+
) {
|
| 78 |
+
response.body()?.let { data ->
|
| 79 |
+
onSuccess(data)
|
| 80 |
+
} ?: run {
|
| 81 |
+
onFailure(response.message())
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
override fun onFailure(call: Call<EmptyResultApiResponse>, t: Throwable) {
|
| 86 |
+
onFailure(t.message.toString())
|
| 87 |
+
}
|
| 88 |
+
})
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
suspend fun trainImage(request: TrainImageApiRequest) : ApiResource<TrainImageApiResponse> = suspendCoroutine { continuation ->
|
| 92 |
+
|
| 93 |
+
val call = apiService.trainImage(request)
|
| 94 |
+
|
| 95 |
+
call.enqueue(object : Callback<TrainImageApiResponse> {
|
| 96 |
+
override fun onResponse(
|
| 97 |
+
call: Call<TrainImageApiResponse>, response: Response<TrainImageApiResponse>
|
| 98 |
+
) {
|
| 99 |
+
response.body()?.let { data ->
|
| 100 |
+
continuation.resume(ApiResource.Success(data))
|
| 101 |
+
} ?: run {
|
| 102 |
+
continuation.resume(ApiResource.Error("Error"))
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
override fun onFailure(call: Call<TrainImageApiResponse>, t: Throwable) {
|
| 107 |
+
continuation.resume(ApiResource.Error(t.message.toString()))
|
| 108 |
+
}
|
| 109 |
+
})
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
fun getImageRelatedness(
|
| 113 |
+
request: ImageRelatednessApiRequest,
|
| 114 |
+
onSuccess: OnSuccess<ApiResponse>,
|
| 115 |
+
onFailure: OnFailure<String>
|
| 116 |
+
) {
|
| 117 |
+
val call = apiService.getImageRelatedness(request)
|
| 118 |
+
|
| 119 |
+
call.enqueue(object : Callback<ApiResponse> {
|
| 120 |
+
override fun onResponse(
|
| 121 |
+
call: Call<ApiResponse>, response: Response<ApiResponse>
|
| 122 |
+
) {
|
| 123 |
+
response.body()?.let { data ->
|
| 124 |
+
onSuccess(data)
|
| 125 |
+
} ?: run {
|
| 126 |
onFailure(response.message())
|
| 127 |
}
|
| 128 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/data/repository/RoomRepository.kt
CHANGED
|
@@ -13,35 +13,35 @@ object RoomRepository {
|
|
| 13 |
private var imageDao = databaseHandler.imageDao()
|
| 14 |
private var contactDao = databaseHandler.contactDao()
|
| 15 |
|
| 16 |
-
fun getAllImages(): MutableLiveData<List<ImageEntity>> {
|
| 17 |
return MutableLiveData(imageDao.getAllData())
|
| 18 |
}
|
| 19 |
|
| 20 |
-
fun insertImage(entity: ImageEntity) {
|
| 21 |
imageDao.insert(entity)
|
| 22 |
}
|
| 23 |
|
| 24 |
-
fun updateImage(entity: ImageEntity) {
|
| 25 |
imageDao.update(entity)
|
| 26 |
}
|
| 27 |
|
| 28 |
-
fun deleteImage(entity: ImageEntity) {
|
| 29 |
imageDao.delete(entity)
|
| 30 |
}
|
| 31 |
|
| 32 |
-
fun getAllContacts(): MutableLiveData<List<ContactEntity>> {
|
| 33 |
return MutableLiveData(contactDao.getAllData())
|
| 34 |
}
|
| 35 |
|
| 36 |
-
fun
|
| 37 |
contactDao.insert(entity)
|
| 38 |
}
|
| 39 |
|
| 40 |
-
fun
|
| 41 |
contactDao.update(entity)
|
| 42 |
}
|
| 43 |
|
| 44 |
-
fun
|
| 45 |
contactDao.delete(entity)
|
| 46 |
}
|
| 47 |
}
|
|
|
|
| 13 |
private var imageDao = databaseHandler.imageDao()
|
| 14 |
private var contactDao = databaseHandler.contactDao()
|
| 15 |
|
| 16 |
+
suspend fun getAllImages(): MutableLiveData<List<ImageEntity>> {
|
| 17 |
return MutableLiveData(imageDao.getAllData())
|
| 18 |
}
|
| 19 |
|
| 20 |
+
suspend fun insertImage(entity: ImageEntity) {
|
| 21 |
imageDao.insert(entity)
|
| 22 |
}
|
| 23 |
|
| 24 |
+
suspend fun updateImage(entity: ImageEntity) {
|
| 25 |
imageDao.update(entity)
|
| 26 |
}
|
| 27 |
|
| 28 |
+
suspend fun deleteImage(entity: ImageEntity) {
|
| 29 |
imageDao.delete(entity)
|
| 30 |
}
|
| 31 |
|
| 32 |
+
suspend fun getAllContacts(): MutableLiveData<List<ContactEntity>> {
|
| 33 |
return MutableLiveData(contactDao.getAllData())
|
| 34 |
}
|
| 35 |
|
| 36 |
+
suspend fun insertContact(entity: ContactEntity) {
|
| 37 |
contactDao.insert(entity)
|
| 38 |
}
|
| 39 |
|
| 40 |
+
suspend fun updateContact(entity: ContactEntity) {
|
| 41 |
contactDao.update(entity)
|
| 42 |
}
|
| 43 |
|
| 44 |
+
suspend fun deleteContact(entity: ContactEntity) {
|
| 45 |
contactDao.delete(entity)
|
| 46 |
}
|
| 47 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/adapters/ChatMainAdapter.kt
CHANGED
|
@@ -7,16 +7,29 @@ import android.view.View
|
|
| 7 |
import android.view.ViewGroup
|
| 8 |
import android.widget.FrameLayout
|
| 9 |
import android.widget.ImageView
|
|
|
|
| 10 |
import android.widget.TextView
|
| 11 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 12 |
import androidx.recyclerview.widget.RecyclerView
|
| 13 |
import com.matthaigh27.chatgptwrapper.R
|
| 14 |
-
import com.matthaigh27.chatgptwrapper.data.models.ChatMessageModel
|
|
|
|
|
|
|
| 15 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
|
|
|
| 16 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.SendSmsWidget
|
|
|
|
|
|
|
| 17 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.helpprompt.HelpPromptWidget
|
| 18 |
-
import com.matthaigh27.chatgptwrapper.utils.Constants
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ImageHelper
|
|
|
|
| 20 |
|
| 21 |
class ChatMainAdapter(
|
| 22 |
context: Context, list: ArrayList<ChatMessageModel>, callbacks: ChatMessageInterface
|
|
@@ -25,6 +38,7 @@ class ChatMainAdapter(
|
|
| 25 |
private val VIEW_TYPE_MSG_SENT = 0
|
| 26 |
private val VIEW_TYPE_MSG_RECEIVED = 1
|
| 27 |
private val VIEW_TYPE_CHAT_WIDGET = 2
|
|
|
|
| 28 |
|
| 29 |
private var context: Context
|
| 30 |
private var callbacks: ChatMessageInterface
|
|
@@ -41,7 +55,7 @@ class ChatMainAdapter(
|
|
| 41 |
|
| 42 |
return when (viewType) {
|
| 43 |
VIEW_TYPE_MSG_SENT -> {
|
| 44 |
-
|
| 45 |
inflater.inflate(
|
| 46 |
R.layout.item_container_sent_message, parent, false
|
| 47 |
)
|
|
@@ -49,13 +63,21 @@ class ChatMainAdapter(
|
|
| 49 |
}
|
| 50 |
|
| 51 |
VIEW_TYPE_MSG_RECEIVED -> {
|
| 52 |
-
|
| 53 |
inflater.inflate(
|
| 54 |
R.layout.item_container_received_message, parent, false
|
| 55 |
)
|
| 56 |
)
|
| 57 |
}
|
| 58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
else -> {
|
| 60 |
ChatWidgetViewHolder(
|
| 61 |
inflater.inflate(
|
|
@@ -78,25 +100,17 @@ class ChatMainAdapter(
|
|
| 78 |
val index = holder.adapterPosition
|
| 79 |
val chatMessageModel: ChatMessageModel = chatMessageList[index]
|
| 80 |
when (chatMessageModel.type) {
|
| 81 |
-
|
| 82 |
-
setMessageData(holder as
|
| 83 |
-
}
|
| 84 |
-
|
| 85 |
-
VIEW_TYPE_MSG_RECEIVED -> {
|
| 86 |
-
setMessageData(holder as ReceivedMessageViewHolder, chatMessageModel)
|
| 87 |
}
|
| 88 |
|
| 89 |
else -> {
|
| 90 |
-
setMessageData(holder as
|
| 91 |
}
|
| 92 |
}
|
| 93 |
}
|
| 94 |
|
| 95 |
-
private fun setMessageData(holder:
|
| 96 |
-
holder.txtMessage.text = data.content
|
| 97 |
-
}
|
| 98 |
-
|
| 99 |
-
private fun setMessageData(holder: ReceivedMessageViewHolder, data: ChatMessageModel) {
|
| 100 |
if (data.hasImage) {
|
| 101 |
data.image?.let { image ->
|
| 102 |
val originBitmap = BitmapFactory.decodeByteArray(image, 0, image.size)
|
|
@@ -114,48 +128,101 @@ class ChatMainAdapter(
|
|
| 114 |
} else {
|
| 115 |
holder.txtMessage.text = data.content
|
| 116 |
holder.imgMessage.visibility = View.GONE
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
}
|
| 119 |
}
|
| 120 |
|
| 121 |
private fun setMessageData(holder: ChatWidgetViewHolder, data: ChatMessageModel) {
|
|
|
|
|
|
|
|
|
|
| 122 |
when (data.content) {
|
| 123 |
-
|
| 124 |
val sendSmsWidget = SendSmsWidget(context).apply {
|
| 125 |
this.callback = callbacks
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
}
|
|
|
|
| 127 |
holder.itemLayout.addView(sendSmsWidget)
|
| 128 |
-
holder.itemLayout.visibility = View.VISIBLE
|
| 129 |
}
|
| 130 |
|
| 131 |
-
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
}
|
| 134 |
|
| 135 |
-
|
|
|
|
| 136 |
|
| 137 |
-
|
| 138 |
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
| 140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
}
|
| 142 |
-
}
|
| 143 |
-
}
|
| 144 |
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
itemLayout = itemView.findViewById<View>(R.id.cl_received_message) as ConstraintLayout
|
| 155 |
}
|
| 156 |
}
|
| 157 |
|
| 158 |
-
inner class
|
| 159 |
RecyclerView.ViewHolder(itemView) {
|
| 160 |
var txtMessage: TextView
|
| 161 |
var imgMessage: ImageView
|
|
@@ -164,16 +231,18 @@ class ChatMainAdapter(
|
|
| 164 |
init {
|
| 165 |
txtMessage = itemView.findViewById<View>(R.id.txt_message) as TextView
|
| 166 |
imgMessage = itemView.findViewById<View>(R.id.img_message) as ImageView
|
| 167 |
-
itemLayout = itemView.findViewById<View>(R.id.
|
| 168 |
}
|
| 169 |
}
|
| 170 |
|
| 171 |
inner class ChatWidgetViewHolder internal constructor(itemView: View) :
|
| 172 |
RecyclerView.ViewHolder(itemView) {
|
| 173 |
var itemLayout: FrameLayout
|
|
|
|
| 174 |
|
| 175 |
init {
|
| 176 |
itemLayout = itemView.findViewById<View>(R.id.fl_widget_message) as FrameLayout
|
|
|
|
| 177 |
}
|
| 178 |
}
|
| 179 |
}
|
|
|
|
| 7 |
import android.view.ViewGroup
|
| 8 |
import android.widget.FrameLayout
|
| 9 |
import android.widget.ImageView
|
| 10 |
+
import android.widget.LinearLayout
|
| 11 |
import android.widget.TextView
|
| 12 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 13 |
import androidx.recyclerview.widget.RecyclerView
|
| 14 |
import com.matthaigh27.chatgptwrapper.R
|
| 15 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.ChatMessageModel
|
| 16 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpPromptModel
|
| 17 |
+
import com.matthaigh27.chatgptwrapper.data.models.chatwidgetprops.ScheduleAlarmProps
|
| 18 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 19 |
+
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.OnHideListener
|
| 20 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.SendSmsWidget
|
| 21 |
+
import com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.alarm.ScheduleAlarmWidget
|
| 22 |
+
import com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.contact.SearchContactWidget
|
| 23 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.helpprompt.HelpPromptWidget
|
| 24 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.PROPS_WIDGET_DESC
|
| 25 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_HELP_PROMPT
|
| 26 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_SCHEDULE_ALARM
|
| 27 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_SEARCH_CONTACT
|
| 28 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_SMS
|
| 29 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ContactHelper.getContactModelById
|
| 30 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ContactHelper.getContacts
|
| 31 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ImageHelper
|
| 32 |
+
import org.json.JSONArray
|
| 33 |
|
| 34 |
class ChatMainAdapter(
|
| 35 |
context: Context, list: ArrayList<ChatMessageModel>, callbacks: ChatMessageInterface
|
|
|
|
| 38 |
private val VIEW_TYPE_MSG_SENT = 0
|
| 39 |
private val VIEW_TYPE_MSG_RECEIVED = 1
|
| 40 |
private val VIEW_TYPE_CHAT_WIDGET = 2
|
| 41 |
+
private val VIEW_TYPE_CHAT_ERROR = 3
|
| 42 |
|
| 43 |
private var context: Context
|
| 44 |
private var callbacks: ChatMessageInterface
|
|
|
|
| 55 |
|
| 56 |
return when (viewType) {
|
| 57 |
VIEW_TYPE_MSG_SENT -> {
|
| 58 |
+
MessageViewHolder(
|
| 59 |
inflater.inflate(
|
| 60 |
R.layout.item_container_sent_message, parent, false
|
| 61 |
)
|
|
|
|
| 63 |
}
|
| 64 |
|
| 65 |
VIEW_TYPE_MSG_RECEIVED -> {
|
| 66 |
+
MessageViewHolder(
|
| 67 |
inflater.inflate(
|
| 68 |
R.layout.item_container_received_message, parent, false
|
| 69 |
)
|
| 70 |
)
|
| 71 |
}
|
| 72 |
|
| 73 |
+
VIEW_TYPE_CHAT_ERROR -> {
|
| 74 |
+
MessageViewHolder(
|
| 75 |
+
inflater.inflate(
|
| 76 |
+
R.layout.item_container_error_message, parent, false
|
| 77 |
+
)
|
| 78 |
+
)
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
else -> {
|
| 82 |
ChatWidgetViewHolder(
|
| 83 |
inflater.inflate(
|
|
|
|
| 100 |
val index = holder.adapterPosition
|
| 101 |
val chatMessageModel: ChatMessageModel = chatMessageList[index]
|
| 102 |
when (chatMessageModel.type) {
|
| 103 |
+
VIEW_TYPE_CHAT_WIDGET -> {
|
| 104 |
+
setMessageData(holder as ChatWidgetViewHolder, chatMessageModel)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
}
|
| 106 |
|
| 107 |
else -> {
|
| 108 |
+
setMessageData(holder as MessageViewHolder, chatMessageModel)
|
| 109 |
}
|
| 110 |
}
|
| 111 |
}
|
| 112 |
|
| 113 |
+
private fun setMessageData(holder: MessageViewHolder, data: ChatMessageModel) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
if (data.hasImage) {
|
| 115 |
data.image?.let { image ->
|
| 116 |
val originBitmap = BitmapFactory.decodeByteArray(image, 0, image.size)
|
|
|
|
| 128 |
} else {
|
| 129 |
holder.txtMessage.text = data.content
|
| 130 |
holder.imgMessage.visibility = View.GONE
|
| 131 |
+
data.content?.let {
|
| 132 |
+
holder.txtMessage.visibility = View.VISIBLE
|
| 133 |
+
} ?: run {
|
| 134 |
+
holder.txtMessage.visibility = View.GONE
|
| 135 |
+
}
|
| 136 |
}
|
| 137 |
}
|
| 138 |
|
| 139 |
private fun setMessageData(holder: ChatWidgetViewHolder, data: ChatMessageModel) {
|
| 140 |
+
holder.itemLayout.visibility = View.VISIBLE
|
| 141 |
+
val index = holder.adapterPosition
|
| 142 |
+
|
| 143 |
when (data.content) {
|
| 144 |
+
TYPE_WIDGET_SMS -> {
|
| 145 |
val sendSmsWidget = SendSmsWidget(context).apply {
|
| 146 |
this.callback = callbacks
|
| 147 |
+
this.hideListener = object : OnHideListener {
|
| 148 |
+
override fun hide() {
|
| 149 |
+
holder.itemLayout.visibility = View.GONE
|
| 150 |
+
chatMessageList.removeAt(index)
|
| 151 |
+
notifyItemRemoved(index)
|
| 152 |
+
}
|
| 153 |
+
}
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
if (data.data != null) {
|
| 157 |
+
val widgetDesc = data.data.asJsonObject[PROPS_WIDGET_DESC].asString
|
| 158 |
+
if (widgetDesc.isNotEmpty()) {
|
| 159 |
+
sendSmsWidget.setPhoneNumber(widgetDesc)
|
| 160 |
+
}
|
| 161 |
}
|
| 162 |
+
|
| 163 |
holder.itemLayout.addView(sendSmsWidget)
|
|
|
|
| 164 |
}
|
| 165 |
|
| 166 |
+
TYPE_WIDGET_HELP_PROMPT -> {
|
| 167 |
+
val widgetDesc = data.data!!.asJsonObject[PROPS_WIDGET_DESC].asString
|
| 168 |
+
val helpPromptWidget =
|
| 169 |
+
HelpPromptWidget(context, HelpPromptModel.init(widgetDesc)).apply {
|
| 170 |
+
this.callback = callbacks
|
| 171 |
+
this.hideListener = object : OnHideListener {
|
| 172 |
+
override fun hide() {
|
| 173 |
+
holder.itemLayout.visibility = View.GONE
|
| 174 |
+
chatMessageList.removeAt(index)
|
| 175 |
+
notifyItemRemoved(index)
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
}
|
| 179 |
+
holder.itemLayout.addView(helpPromptWidget)
|
| 180 |
}
|
| 181 |
|
| 182 |
+
TYPE_WIDGET_SEARCH_CONTACT -> {
|
| 183 |
+
holder.llSearchContact.visibility = View.VISIBLE
|
| 184 |
|
| 185 |
+
val contacts = getContacts(context)
|
| 186 |
|
| 187 |
+
val contactIds = JSONArray(data.data!!.asString.replace("'", "\""))
|
| 188 |
+
for (i in 0 until contactIds.length()) {
|
| 189 |
+
val contactId = contactIds[i].toString()
|
| 190 |
+
val contact = getContactModelById(contactId, contacts)
|
| 191 |
|
| 192 |
+
val searchContactWidget = SearchContactWidget(context, contact).apply {
|
| 193 |
+
this.callback = callbacks
|
| 194 |
+
}
|
| 195 |
+
holder.llSearchContact.addView(searchContactWidget)
|
| 196 |
+
}
|
| 197 |
}
|
|
|
|
|
|
|
| 198 |
|
| 199 |
+
TYPE_WIDGET_SCHEDULE_ALARM -> {
|
| 200 |
+
var props = ScheduleAlarmProps()
|
| 201 |
+
data.data?.run {
|
| 202 |
+
val widgetDesc = data.data.asJsonObject[PROPS_WIDGET_DESC].asString
|
| 203 |
+
props = ScheduleAlarmProps.init(widgetDesc)
|
| 204 |
+
}
|
| 205 |
+
val scheduleAlarmWidget =
|
| 206 |
+
ScheduleAlarmWidget(context, props.time, props.label, props.repeat).apply {
|
| 207 |
+
this.callback = callbacks
|
| 208 |
+
this.hideListener = object : OnHideListener {
|
| 209 |
+
override fun hide() {
|
| 210 |
+
holder.itemLayout.visibility = View.GONE
|
| 211 |
+
chatMessageList.removeAt(index)
|
| 212 |
+
notifyItemRemoved(index)
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
}
|
| 216 |
+
holder.itemLayout.addView(scheduleAlarmWidget)
|
| 217 |
+
}
|
| 218 |
|
| 219 |
+
else -> {
|
| 220 |
+
holder.itemLayout.visibility = View.GONE
|
| 221 |
+
}
|
|
|
|
| 222 |
}
|
| 223 |
}
|
| 224 |
|
| 225 |
+
inner class MessageViewHolder internal constructor(itemView: View) :
|
| 226 |
RecyclerView.ViewHolder(itemView) {
|
| 227 |
var txtMessage: TextView
|
| 228 |
var imgMessage: ImageView
|
|
|
|
| 231 |
init {
|
| 232 |
txtMessage = itemView.findViewById<View>(R.id.txt_message) as TextView
|
| 233 |
imgMessage = itemView.findViewById<View>(R.id.img_message) as ImageView
|
| 234 |
+
itemLayout = itemView.findViewById<View>(R.id.cl_message) as ConstraintLayout
|
| 235 |
}
|
| 236 |
}
|
| 237 |
|
| 238 |
inner class ChatWidgetViewHolder internal constructor(itemView: View) :
|
| 239 |
RecyclerView.ViewHolder(itemView) {
|
| 240 |
var itemLayout: FrameLayout
|
| 241 |
+
var llSearchContact: LinearLayout
|
| 242 |
|
| 243 |
init {
|
| 244 |
itemLayout = itemView.findViewById<View>(R.id.fl_widget_message) as FrameLayout
|
| 245 |
+
llSearchContact = itemView.findViewById<View>(R.id.ll_contacts_widget) as LinearLayout
|
| 246 |
}
|
| 247 |
}
|
| 248 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/fragments/ChatMainFragment.kt
CHANGED
|
@@ -13,17 +13,19 @@ import android.view.animation.RotateAnimation
|
|
| 13 |
import android.widget.EditText
|
| 14 |
import android.widget.ImageView
|
| 15 |
import android.widget.LinearLayout
|
| 16 |
-
import android.widget.Toast
|
| 17 |
import androidx.fragment.app.Fragment
|
| 18 |
import androidx.lifecycle.Observer
|
| 19 |
import androidx.lifecycle.ViewModelProvider
|
| 20 |
import androidx.recyclerview.widget.LinearLayoutManager
|
| 21 |
import androidx.recyclerview.widget.RecyclerView
|
| 22 |
import com.google.gson.JsonElement
|
|
|
|
| 23 |
import com.matthaigh27.chatgptwrapper.R
|
| 24 |
-
import com.matthaigh27.chatgptwrapper.data.models.ChatMessageModel
|
| 25 |
-
import com.matthaigh27.chatgptwrapper.data.models.HelpCommandModel
|
| 26 |
-
import com.matthaigh27.chatgptwrapper.data.models.HelpPromptModel
|
|
|
|
|
|
|
| 27 |
import com.matthaigh27.chatgptwrapper.data.remote.ApiResource
|
| 28 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
| 29 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.adapters.ChatMainAdapter
|
|
@@ -32,26 +34,33 @@ import com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.toolbar.ChatToolsWidg
|
|
| 32 |
import com.matthaigh27.chatgptwrapper.ui.chat.viewmodel.ChatViewModel
|
| 33 |
import com.matthaigh27.chatgptwrapper.utils.Constants.ERROR_MSG_NOEXIST_COMMAND
|
| 34 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ALL
|
|
|
|
|
|
|
| 35 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_ALERT
|
| 36 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_BROWSER
|
| 37 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_CONTACT
|
| 38 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_IMAGE
|
| 39 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_MESSAGE
|
| 40 |
-
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_SMS
|
| 41 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_HELP_PROMPT
|
|
|
|
|
|
|
| 42 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_SMS
|
|
|
|
| 43 |
import com.matthaigh27.chatgptwrapper.utils.helpers.Converter.stringToHelpPromptList
|
| 44 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.getHelpCommandFromStr
|
| 45 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.isMainHelpCommand
|
| 46 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.makePromptItemUsage
|
| 47 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.makePromptUsage
|
| 48 |
import com.matthaigh27.chatgptwrapper.utils.helpers.ui.NoNewLineInputFilter
|
|
|
|
|
|
|
| 49 |
|
| 50 |
class ChatMainFragment : Fragment(), OnClickListener {
|
| 51 |
|
| 52 |
private val TYPE_CHAT_SENT = 0
|
| 53 |
private val TYPE_CHAT_RECEIVE = 1
|
| 54 |
private val TYPE_CHAT_WIDGET = 2
|
|
|
|
| 55 |
|
| 56 |
private lateinit var rootView: View
|
| 57 |
lateinit var viewModel: ChatViewModel
|
|
@@ -68,6 +77,11 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 68 |
private var chatToolsWidget: ChatToolsWidget? = null
|
| 69 |
private var helpPromptList: ArrayList<HelpPromptModel>? = null
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
override fun onCreateView(
|
| 72 |
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
| 73 |
): View {
|
|
@@ -87,13 +101,15 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 87 |
fetchAllCommands()
|
| 88 |
}
|
| 89 |
|
|
|
|
|
|
|
| 90 |
private fun initViewModel() {
|
| 91 |
viewModel = ViewModelProvider(this)[ChatViewModel::class.java]
|
| 92 |
}
|
| 93 |
|
| 94 |
private fun initLoadingRotate() {
|
| 95 |
loadingRotate = RotateAnimation(/* fromDegrees = */ 0f, /* toDegrees = */
|
| 96 |
-
|
| 97 |
Animation.RELATIVE_TO_SELF, /* pivotXValue = */
|
| 98 |
0.5f, /* pivotYType = */
|
| 99 |
Animation.RELATIVE_TO_SELF, /* pivotYValue = */
|
|
@@ -135,24 +151,28 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 135 |
}
|
| 136 |
|
| 137 |
private fun initChatToolsWidget() {
|
| 138 |
-
chatToolsWidget = ChatToolsWidget(requireContext(), requireActivity())
|
|
|
|
|
|
|
| 139 |
val llToolBar = rootView.findViewById<LinearLayout>(R.id.ll_toolbar)
|
| 140 |
llToolBar.addView(chatToolsWidget)
|
| 141 |
}
|
| 142 |
|
| 143 |
-
private fun showToast(message: String) {
|
| 144 |
-
Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show()
|
| 145 |
-
}
|
| 146 |
-
|
| 147 |
private fun showLoading(isLoading: Boolean) {
|
| 148 |
val imgLoading = rootView.findViewById<ImageView>(R.id.sp_loading)
|
| 149 |
|
| 150 |
if (isLoading) {
|
| 151 |
imgLoading.startAnimation(loadingRotate)
|
| 152 |
imgLoading.visibility = View.VISIBLE
|
|
|
|
|
|
|
| 153 |
} else {
|
| 154 |
-
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
}
|
| 157 |
}
|
| 158 |
|
|
@@ -163,18 +183,44 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 163 |
hasImage: Boolean = false,
|
| 164 |
image: ByteArray? = null
|
| 165 |
) {
|
| 166 |
-
addChatItemToList(ChatMessageModel(type, content, data, hasImage, image))
|
| 167 |
when (type) {
|
| 168 |
TYPE_CHAT_SENT -> {
|
| 169 |
if (content!!.isNotEmpty() && content.first() == '/') {
|
| 170 |
openHelpPromptWidget(content)
|
| 171 |
return
|
| 172 |
}
|
| 173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
}
|
| 175 |
}
|
| 176 |
}
|
| 177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
@SuppressLint("NotifyDataSetChanged")
|
| 179 |
private fun addChatItemToList(chatModel: ChatMessageModel) {
|
| 180 |
edtMessageInput?.setText("")
|
|
@@ -184,6 +230,18 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 184 |
rvChatList?.scrollToPosition(chatMessageList.size - 1)
|
| 185 |
}
|
| 186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
private fun openHelpPromptWidget(message: String) {
|
| 188 |
try {
|
| 189 |
val command: HelpCommandModel = getHelpCommandFromStr(message)
|
|
@@ -201,17 +259,22 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 201 |
model.name == command.main
|
| 202 |
}
|
| 203 |
|
| 204 |
-
if(data.isEmpty()) {
|
| 205 |
addMessage(
|
| 206 |
type = TYPE_CHAT_RECEIVE, content = ERROR_MSG_NOEXIST_COMMAND
|
| 207 |
)
|
| 208 |
} else {
|
|
|
|
|
|
|
|
|
|
| 209 |
addMessage(
|
| 210 |
type = TYPE_CHAT_WIDGET,
|
| 211 |
content = TYPE_WIDGET_HELP_PROMPT,
|
| 212 |
-
data =
|
| 213 |
)
|
| 214 |
}
|
|
|
|
|
|
|
| 215 |
}
|
| 216 |
}
|
| 217 |
}
|
|
@@ -229,7 +292,7 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 229 |
}
|
| 230 |
} catch (e: Exception) {
|
| 231 |
e.printStackTrace()
|
| 232 |
-
|
| 233 |
}
|
| 234 |
}
|
| 235 |
|
|
@@ -251,7 +314,7 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 251 |
|
| 252 |
is ApiResource.Error -> {
|
| 253 |
showLoading(false)
|
| 254 |
-
|
| 255 |
}
|
| 256 |
}
|
| 257 |
})
|
|
@@ -263,35 +326,22 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 263 |
is ApiResource.Loading -> {
|
| 264 |
showLoading(true)
|
| 265 |
}
|
|
|
|
| 266 |
is ApiResource.Success -> {
|
| 267 |
showLoading(false)
|
| 268 |
val apiResponse = resource.data
|
| 269 |
when (apiResponse?.result?.program) {
|
| 270 |
-
TYPE_RESPONSE_MESSAGE ->
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
TYPE_RESPONSE_ALERT -> {
|
| 277 |
-
|
| 278 |
-
}
|
| 279 |
-
TYPE_RESPONSE_CONTACT -> {
|
| 280 |
-
|
| 281 |
-
}
|
| 282 |
-
TYPE_RESPONSE_IMAGE -> {
|
| 283 |
-
fetchResponseImage(apiResponse)
|
| 284 |
-
}
|
| 285 |
-
TYPE_RESPONSE_SMS -> {
|
| 286 |
-
|
| 287 |
-
}
|
| 288 |
-
else -> {
|
| 289 |
-
|
| 290 |
-
}
|
| 291 |
}
|
| 292 |
}
|
|
|
|
| 293 |
is ApiResource.Error -> {
|
| 294 |
-
|
| 295 |
showLoading(false)
|
| 296 |
}
|
| 297 |
}
|
|
@@ -325,13 +375,38 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 325 |
}
|
| 326 |
|
| 327 |
is ApiResource.Error -> {
|
| 328 |
-
|
| 329 |
showLoading(false)
|
| 330 |
}
|
| 331 |
}
|
| 332 |
})
|
| 333 |
}
|
| 334 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 335 |
|
| 336 |
private fun initChatInterface() {
|
| 337 |
chatMessageInterface = object : ChatMessageInterface {
|
|
@@ -350,21 +425,81 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 350 |
}
|
| 351 |
|
| 352 |
override fun sentHelpPrompt(prompt: String) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 353 |
}
|
| 354 |
|
| 355 |
override fun canceledHelpPrompt() {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 356 |
}
|
| 357 |
|
| 358 |
override fun doVoiceCall(phoneNumber: String) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
}
|
| 360 |
|
| 361 |
override fun doVideoCall(phoneNumber: String) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 362 |
}
|
| 363 |
|
| 364 |
override fun sendSmsWithPhoneNumber(phoneNumber: String) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
}
|
| 366 |
|
| 367 |
override fun pickImage(isSuccess: Boolean, data: ByteArray?) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
}
|
| 369 |
}
|
| 370 |
}
|
|
@@ -380,4 +515,10 @@ class ChatMainFragment : Fragment(), OnClickListener {
|
|
| 380 |
}
|
| 381 |
}
|
| 382 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 383 |
}
|
|
|
|
| 13 |
import android.widget.EditText
|
| 14 |
import android.widget.ImageView
|
| 15 |
import android.widget.LinearLayout
|
|
|
|
| 16 |
import androidx.fragment.app.Fragment
|
| 17 |
import androidx.lifecycle.Observer
|
| 18 |
import androidx.lifecycle.ViewModelProvider
|
| 19 |
import androidx.recyclerview.widget.LinearLayoutManager
|
| 20 |
import androidx.recyclerview.widget.RecyclerView
|
| 21 |
import com.google.gson.JsonElement
|
| 22 |
+
import com.google.gson.JsonObject
|
| 23 |
import com.matthaigh27.chatgptwrapper.R
|
| 24 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.ChatMessageModel
|
| 25 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpCommandModel
|
| 26 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpPromptModel
|
| 27 |
+
import com.matthaigh27.chatgptwrapper.data.models.chatwidgetprops.ScheduleAlarmProps
|
| 28 |
+
import com.matthaigh27.chatgptwrapper.data.models.common.Time
|
| 29 |
import com.matthaigh27.chatgptwrapper.data.remote.ApiResource
|
| 30 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
| 31 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.adapters.ChatMainAdapter
|
|
|
|
| 34 |
import com.matthaigh27.chatgptwrapper.ui.chat.viewmodel.ChatViewModel
|
| 35 |
import com.matthaigh27.chatgptwrapper.utils.Constants.ERROR_MSG_NOEXIST_COMMAND
|
| 36 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ALL
|
| 37 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.PROPS_WIDGET_DESC
|
| 38 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_ALARM
|
| 39 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_ALERT
|
| 40 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_BROWSER
|
| 41 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_CONTACT
|
| 42 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_IMAGE
|
| 43 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_RESPONSE_MESSAGE
|
|
|
|
| 44 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_HELP_PROMPT
|
| 45 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_SCHEDULE_ALARM
|
| 46 |
+
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_SEARCH_CONTACT
|
| 47 |
import com.matthaigh27.chatgptwrapper.utils.Constants.TYPE_WIDGET_SMS
|
| 48 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.Converter
|
| 49 |
import com.matthaigh27.chatgptwrapper.utils.helpers.Converter.stringToHelpPromptList
|
| 50 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.getHelpCommandFromStr
|
| 51 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.isMainHelpCommand
|
| 52 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.makePromptItemUsage
|
| 53 |
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper.makePromptUsage
|
| 54 |
import com.matthaigh27.chatgptwrapper.utils.helpers.ui.NoNewLineInputFilter
|
| 55 |
+
import org.json.JSONArray
|
| 56 |
+
import java.util.Calendar
|
| 57 |
|
| 58 |
class ChatMainFragment : Fragment(), OnClickListener {
|
| 59 |
|
| 60 |
private val TYPE_CHAT_SENT = 0
|
| 61 |
private val TYPE_CHAT_RECEIVE = 1
|
| 62 |
private val TYPE_CHAT_WIDGET = 2
|
| 63 |
+
private val TYPE_CHAT_ERROR = 3
|
| 64 |
|
| 65 |
private lateinit var rootView: View
|
| 66 |
lateinit var viewModel: ChatViewModel
|
|
|
|
| 77 |
private var chatToolsWidget: ChatToolsWidget? = null
|
| 78 |
private var helpPromptList: ArrayList<HelpPromptModel>? = null
|
| 79 |
|
| 80 |
+
private var currentSelectedImage: ByteArray? = null
|
| 81 |
+
private var currentUploadedImageName: String? = null
|
| 82 |
+
private var isImagePicked: Boolean = false
|
| 83 |
+
private var showloadingCount = 0
|
| 84 |
+
|
| 85 |
override fun onCreateView(
|
| 86 |
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
| 87 |
): View {
|
|
|
|
| 101 |
fetchAllCommands()
|
| 102 |
}
|
| 103 |
|
| 104 |
+
|
| 105 |
+
|
| 106 |
private fun initViewModel() {
|
| 107 |
viewModel = ViewModelProvider(this)[ChatViewModel::class.java]
|
| 108 |
}
|
| 109 |
|
| 110 |
private fun initLoadingRotate() {
|
| 111 |
loadingRotate = RotateAnimation(/* fromDegrees = */ 0f, /* toDegrees = */
|
| 112 |
+
720f, /* pivotXType = */
|
| 113 |
Animation.RELATIVE_TO_SELF, /* pivotXValue = */
|
| 114 |
0.5f, /* pivotYType = */
|
| 115 |
Animation.RELATIVE_TO_SELF, /* pivotYValue = */
|
|
|
|
| 151 |
}
|
| 152 |
|
| 153 |
private fun initChatToolsWidget() {
|
| 154 |
+
chatToolsWidget = ChatToolsWidget(requireContext(), requireActivity()).apply {
|
| 155 |
+
this.callback = chatMessageInterface
|
| 156 |
+
}
|
| 157 |
val llToolBar = rootView.findViewById<LinearLayout>(R.id.ll_toolbar)
|
| 158 |
llToolBar.addView(chatToolsWidget)
|
| 159 |
}
|
| 160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
private fun showLoading(isLoading: Boolean) {
|
| 162 |
val imgLoading = rootView.findViewById<ImageView>(R.id.sp_loading)
|
| 163 |
|
| 164 |
if (isLoading) {
|
| 165 |
imgLoading.startAnimation(loadingRotate)
|
| 166 |
imgLoading.visibility = View.VISIBLE
|
| 167 |
+
edtMessageInput?.isEnabled = false
|
| 168 |
+
showloadingCount++
|
| 169 |
} else {
|
| 170 |
+
showloadingCount--
|
| 171 |
+
if(showloadingCount == 0) {
|
| 172 |
+
imgLoading.clearAnimation()
|
| 173 |
+
imgLoading.visibility = View.GONE
|
| 174 |
+
edtMessageInput?.isEnabled = true
|
| 175 |
+
}
|
| 176 |
}
|
| 177 |
}
|
| 178 |
|
|
|
|
| 183 |
hasImage: Boolean = false,
|
| 184 |
image: ByteArray? = null
|
| 185 |
) {
|
|
|
|
| 186 |
when (type) {
|
| 187 |
TYPE_CHAT_SENT -> {
|
| 188 |
if (content!!.isNotEmpty() && content.first() == '/') {
|
| 189 |
openHelpPromptWidget(content)
|
| 190 |
return
|
| 191 |
}
|
| 192 |
+
if (isImagePicked) {
|
| 193 |
+
addChatItemToList(
|
| 194 |
+
ChatMessageModel(
|
| 195 |
+
type = type,
|
| 196 |
+
content = content,
|
| 197 |
+
data = data,
|
| 198 |
+
hasImage = true,
|
| 199 |
+
image = currentSelectedImage
|
| 200 |
+
)
|
| 201 |
+
)
|
| 202 |
+
isImagePicked = false
|
| 203 |
+
} else {
|
| 204 |
+
addChatItemToList(ChatMessageModel(type, content, data, hasImage, image))
|
| 205 |
+
sendNotification(content)
|
| 206 |
+
}
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
else -> {
|
| 210 |
+
addChatItemToList(ChatMessageModel(type, content, data, hasImage, image))
|
| 211 |
}
|
| 212 |
}
|
| 213 |
}
|
| 214 |
|
| 215 |
+
private fun addErrorMessage(
|
| 216 |
+
message: String
|
| 217 |
+
) {
|
| 218 |
+
addMessage(
|
| 219 |
+
type = TYPE_CHAT_RECEIVE,
|
| 220 |
+
content = message
|
| 221 |
+
)
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
@SuppressLint("NotifyDataSetChanged")
|
| 225 |
private fun addChatItemToList(chatModel: ChatMessageModel) {
|
| 226 |
edtMessageInput?.setText("")
|
|
|
|
| 230 |
rvChatList?.scrollToPosition(chatMessageList.size - 1)
|
| 231 |
}
|
| 232 |
|
| 233 |
+
private fun trainContacts() {
|
| 234 |
+
viewModel.trainContacts().observe(viewLifecycleOwner, Observer { state ->
|
| 235 |
+
showLoading(state)
|
| 236 |
+
})
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
private fun trainImages() {
|
| 240 |
+
viewModel.trainImages().observe(viewLifecycleOwner, Observer { state ->
|
| 241 |
+
showLoading(state)
|
| 242 |
+
})
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
private fun openHelpPromptWidget(message: String) {
|
| 246 |
try {
|
| 247 |
val command: HelpCommandModel = getHelpCommandFromStr(message)
|
|
|
|
| 259 |
model.name == command.main
|
| 260 |
}
|
| 261 |
|
| 262 |
+
if (data.isEmpty()) {
|
| 263 |
addMessage(
|
| 264 |
type = TYPE_CHAT_RECEIVE, content = ERROR_MSG_NOEXIST_COMMAND
|
| 265 |
)
|
| 266 |
} else {
|
| 267 |
+
val widgetDesc = JsonObject().apply {
|
| 268 |
+
this.addProperty(PROPS_WIDGET_DESC, data[0].toString())
|
| 269 |
+
}
|
| 270 |
addMessage(
|
| 271 |
type = TYPE_CHAT_WIDGET,
|
| 272 |
content = TYPE_WIDGET_HELP_PROMPT,
|
| 273 |
+
data = widgetDesc
|
| 274 |
)
|
| 275 |
}
|
| 276 |
+
} ?: run {
|
| 277 |
+
addErrorMessage("Help commands don't exist.")
|
| 278 |
}
|
| 279 |
}
|
| 280 |
}
|
|
|
|
| 292 |
}
|
| 293 |
} catch (e: Exception) {
|
| 294 |
e.printStackTrace()
|
| 295 |
+
addErrorMessage(e.message.toString())
|
| 296 |
}
|
| 297 |
}
|
| 298 |
|
|
|
|
| 314 |
|
| 315 |
is ApiResource.Error -> {
|
| 316 |
showLoading(false)
|
| 317 |
+
addErrorMessage(resource.message!!)
|
| 318 |
}
|
| 319 |
}
|
| 320 |
})
|
|
|
|
| 326 |
is ApiResource.Loading -> {
|
| 327 |
showLoading(true)
|
| 328 |
}
|
| 329 |
+
|
| 330 |
is ApiResource.Success -> {
|
| 331 |
showLoading(false)
|
| 332 |
val apiResponse = resource.data
|
| 333 |
when (apiResponse?.result?.program) {
|
| 334 |
+
TYPE_RESPONSE_MESSAGE -> addMessage(TYPE_CHAT_RECEIVE, apiResponse.result.content.toString())
|
| 335 |
+
TYPE_RESPONSE_BROWSER -> fetchResponseBrowser(apiResponse)
|
| 336 |
+
TYPE_RESPONSE_CONTACT -> fetchResponseContact(apiResponse)
|
| 337 |
+
TYPE_RESPONSE_IMAGE -> fetchResponseImage(apiResponse)
|
| 338 |
+
TYPE_RESPONSE_ALARM -> fetchResponseAlarm(apiResponse)
|
| 339 |
+
else -> addMessage(TYPE_CHAT_RECEIVE, apiResponse!!.result.toString())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
}
|
| 341 |
}
|
| 342 |
+
|
| 343 |
is ApiResource.Error -> {
|
| 344 |
+
addErrorMessage(resource.message!!)
|
| 345 |
showLoading(false)
|
| 346 |
}
|
| 347 |
}
|
|
|
|
| 375 |
}
|
| 376 |
|
| 377 |
is ApiResource.Error -> {
|
| 378 |
+
addErrorMessage(resource.message!!)
|
| 379 |
showLoading(false)
|
| 380 |
}
|
| 381 |
}
|
| 382 |
})
|
| 383 |
}
|
| 384 |
|
| 385 |
+
private fun fetchResponseContact(apiResponse: ApiResponse) {
|
| 386 |
+
val contactIds = JSONArray(apiResponse.result.content.asString.replace("'", "\""))
|
| 387 |
+
if (contactIds.length() > 0) {
|
| 388 |
+
addMessage(
|
| 389 |
+
type = TYPE_CHAT_WIDGET,
|
| 390 |
+
content = TYPE_WIDGET_SEARCH_CONTACT,
|
| 391 |
+
data = apiResponse.result.content
|
| 392 |
+
)
|
| 393 |
+
} else {
|
| 394 |
+
addMessage(
|
| 395 |
+
type = TYPE_CHAT_RECEIVE,
|
| 396 |
+
content = "Contacts that you are looking for don't exist.",
|
| 397 |
+
)
|
| 398 |
+
}
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
private fun fetchResponseAlarm(apiResponse: ApiResponse) {
|
| 402 |
+
val time: Time = Converter.stringToTime(apiResponse.result.content.asJsonObject.get("time").asString)
|
| 403 |
+
val label = apiResponse.result.content.asJsonObject.get("label").asString
|
| 404 |
+
val props = ScheduleAlarmProps(time, label)
|
| 405 |
+
val widgetDesc = JsonObject().apply {
|
| 406 |
+
this.addProperty(PROPS_WIDGET_DESC, props.toString())
|
| 407 |
+
}
|
| 408 |
+
addMessage(TYPE_CHAT_WIDGET, TYPE_WIDGET_SCHEDULE_ALARM, widgetDesc)
|
| 409 |
+
}
|
| 410 |
|
| 411 |
private fun initChatInterface() {
|
| 412 |
chatMessageInterface = object : ChatMessageInterface {
|
|
|
|
| 425 |
}
|
| 426 |
|
| 427 |
override fun sentHelpPrompt(prompt: String) {
|
| 428 |
+
addMessage(
|
| 429 |
+
type = TYPE_CHAT_SENT,
|
| 430 |
+
content = prompt
|
| 431 |
+
)
|
| 432 |
}
|
| 433 |
|
| 434 |
override fun canceledHelpPrompt() {
|
| 435 |
+
addMessage(
|
| 436 |
+
type = TYPE_CHAT_RECEIVE,
|
| 437 |
+
content = "You canceled Help prompt."
|
| 438 |
+
)
|
| 439 |
}
|
| 440 |
|
| 441 |
override fun doVoiceCall(phoneNumber: String) {
|
| 442 |
+
addMessage(
|
| 443 |
+
type = TYPE_CHAT_RECEIVE,
|
| 444 |
+
content = "You made a voice call to $phoneNumber"
|
| 445 |
+
)
|
| 446 |
}
|
| 447 |
|
| 448 |
override fun doVideoCall(phoneNumber: String) {
|
| 449 |
+
addMessage(
|
| 450 |
+
type = TYPE_CHAT_RECEIVE,
|
| 451 |
+
content = "You made a video call to $phoneNumber"
|
| 452 |
+
)
|
| 453 |
}
|
| 454 |
|
| 455 |
override fun sendSmsWithPhoneNumber(phoneNumber: String) {
|
| 456 |
+
val widgetDesc = JsonObject().apply {
|
| 457 |
+
this.addProperty(PROPS_WIDGET_DESC, phoneNumber)
|
| 458 |
+
}
|
| 459 |
+
addMessage(
|
| 460 |
+
type = TYPE_CHAT_WIDGET,
|
| 461 |
+
content = TYPE_WIDGET_SMS,
|
| 462 |
+
data = widgetDesc
|
| 463 |
+
)
|
| 464 |
}
|
| 465 |
|
| 466 |
override fun pickImage(isSuccess: Boolean, data: ByteArray?) {
|
| 467 |
+
if (!isSuccess)
|
| 468 |
+
addErrorMessage("Fail to pick image")
|
| 469 |
+
viewModel.uploadImageToFirebase(data!!)
|
| 470 |
+
.observe(viewLifecycleOwner, Observer { resource ->
|
| 471 |
+
when (resource) {
|
| 472 |
+
is ApiResource.Loading -> {
|
| 473 |
+
showLoading(true)
|
| 474 |
+
}
|
| 475 |
+
|
| 476 |
+
is ApiResource.Success -> {
|
| 477 |
+
showLoading(false)
|
| 478 |
+
currentSelectedImage = data
|
| 479 |
+
currentUploadedImageName = resource.data
|
| 480 |
+
isImagePicked = true
|
| 481 |
+
}
|
| 482 |
+
|
| 483 |
+
is ApiResource.Error -> {
|
| 484 |
+
addErrorMessage(resource.message!!)
|
| 485 |
+
showLoading(false)
|
| 486 |
+
}
|
| 487 |
+
}
|
| 488 |
+
})
|
| 489 |
+
}
|
| 490 |
+
|
| 491 |
+
override fun setAlarm(hours: Int, minutes: Int, label: String) {
|
| 492 |
+
addMessage(
|
| 493 |
+
type = TYPE_CHAT_RECEIVE,
|
| 494 |
+
content = "You set an alarm for $hours:$minutes with the label($label)"
|
| 495 |
+
)
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
override fun cancelAlarm() {
|
| 499 |
+
addMessage(
|
| 500 |
+
type = TYPE_CHAT_RECEIVE,
|
| 501 |
+
content = "You canceled setting an alarm."
|
| 502 |
+
)
|
| 503 |
}
|
| 504 |
}
|
| 505 |
}
|
|
|
|
| 515 |
}
|
| 516 |
}
|
| 517 |
}
|
| 518 |
+
|
| 519 |
+
override fun onResume() {
|
| 520 |
+
super.onResume()
|
| 521 |
+
trainImages()
|
| 522 |
+
trainContacts()
|
| 523 |
+
}
|
| 524 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/interfaces/ChatMessageInterface.kt
CHANGED
|
@@ -9,4 +9,6 @@ interface ChatMessageInterface {
|
|
| 9 |
fun doVideoCall(phoneNumber: String)
|
| 10 |
fun sendSmsWithPhoneNumber(phoneNumber: String)
|
| 11 |
fun pickImage(isSuccess: Boolean, data: ByteArray? = null)
|
|
|
|
|
|
|
| 12 |
}
|
|
|
|
| 9 |
fun doVideoCall(phoneNumber: String)
|
| 10 |
fun sendSmsWithPhoneNumber(phoneNumber: String)
|
| 11 |
fun pickImage(isSuccess: Boolean, data: ByteArray? = null)
|
| 12 |
+
fun setAlarm(hours: Int, minutes:Int, label: String)
|
| 13 |
+
fun cancelAlarm()
|
| 14 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/interfaces/OnHideListener.kt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces
|
| 2 |
+
|
| 3 |
+
interface OnHideListener {
|
| 4 |
+
fun hide()
|
| 5 |
+
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/SendSmsWidget.kt
CHANGED
|
@@ -10,6 +10,7 @@ import android.widget.Toast
|
|
| 10 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 11 |
import com.matthaigh27.chatgptwrapper.R
|
| 12 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
|
|
|
| 13 |
|
| 14 |
class SendSmsWidget(
|
| 15 |
context: Context, attrs: AttributeSet? = null
|
|
@@ -24,6 +25,7 @@ class SendSmsWidget(
|
|
| 24 |
private val btnCancel: Button
|
| 25 |
|
| 26 |
var callback: ChatMessageInterface? = null
|
|
|
|
| 27 |
|
| 28 |
init {
|
| 29 |
inflate(context, R.layout.widget_send_sms, this)
|
|
@@ -47,12 +49,12 @@ class SendSmsWidget(
|
|
| 47 |
).show()
|
| 48 |
return@setOnClickListener
|
| 49 |
}
|
| 50 |
-
hide()
|
| 51 |
callback?.sentSms(edtPhoneNumber.text.toString(), edtMessage.text.toString())
|
| 52 |
}
|
| 53 |
|
| 54 |
btnCancel.setOnClickListener {
|
| 55 |
-
hide()
|
| 56 |
callback?.canceledSms()
|
| 57 |
}
|
| 58 |
}
|
|
@@ -60,10 +62,4 @@ class SendSmsWidget(
|
|
| 60 |
fun setPhoneNumber(phonenumber: String) {
|
| 61 |
edtPhoneNumber.setText(phonenumber)
|
| 62 |
}
|
| 63 |
-
|
| 64 |
-
fun hide() {
|
| 65 |
-
this.visibility = View.GONE
|
| 66 |
-
edtMessage.setText("")
|
| 67 |
-
edtPhoneNumber.setText("")
|
| 68 |
-
}
|
| 69 |
}
|
|
|
|
| 10 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 11 |
import com.matthaigh27.chatgptwrapper.R
|
| 12 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 13 |
+
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.OnHideListener
|
| 14 |
|
| 15 |
class SendSmsWidget(
|
| 16 |
context: Context, attrs: AttributeSet? = null
|
|
|
|
| 25 |
private val btnCancel: Button
|
| 26 |
|
| 27 |
var callback: ChatMessageInterface? = null
|
| 28 |
+
var hideListener: OnHideListener? = null
|
| 29 |
|
| 30 |
init {
|
| 31 |
inflate(context, R.layout.widget_send_sms, this)
|
|
|
|
| 49 |
).show()
|
| 50 |
return@setOnClickListener
|
| 51 |
}
|
| 52 |
+
hideListener?.hide()
|
| 53 |
callback?.sentSms(edtPhoneNumber.text.toString(), edtMessage.text.toString())
|
| 54 |
}
|
| 55 |
|
| 56 |
btnCancel.setOnClickListener {
|
| 57 |
+
hideListener?.hide()
|
| 58 |
callback?.canceledSms()
|
| 59 |
}
|
| 60 |
}
|
|
|
|
| 62 |
fun setPhoneNumber(phonenumber: String) {
|
| 63 |
edtPhoneNumber.setText(phonenumber)
|
| 64 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/alarm/DayOfWeekItem.kt
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.alarm
|
| 2 |
+
|
| 3 |
+
import android.content.Context
|
| 4 |
+
import android.util.AttributeSet
|
| 5 |
+
import android.view.View
|
| 6 |
+
import android.view.ViewGroup
|
| 7 |
+
import android.widget.LinearLayout
|
| 8 |
+
import android.widget.TextView
|
| 9 |
+
import androidx.core.view.setPadding
|
| 10 |
+
import com.matthaigh27.chatgptwrapper.R
|
| 11 |
+
|
| 12 |
+
class DayOfWeekItem(
|
| 13 |
+
context: Context, day: String, attrs: AttributeSet? = null
|
| 14 |
+
) : LinearLayout(context, attrs), View.OnClickListener {
|
| 15 |
+
|
| 16 |
+
private val context: Context
|
| 17 |
+
private var txtDay: TextView
|
| 18 |
+
var isChecked = false
|
| 19 |
+
|
| 20 |
+
init {
|
| 21 |
+
inflate(context, R.layout.item_day_of_week, this)
|
| 22 |
+
this.context = context
|
| 23 |
+
|
| 24 |
+
layoutParams = LayoutParams(
|
| 25 |
+
0,
|
| 26 |
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
| 27 |
+
1f
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
val padding = context.resources.getDimensionPixelSize(R.dimen.spacing_tiny)
|
| 31 |
+
|
| 32 |
+
txtDay = findViewById(R.id.txt_day)
|
| 33 |
+
txtDay.text = day
|
| 34 |
+
|
| 35 |
+
txtDay.setOnClickListener(this)
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
override fun onClick(view: View?) {
|
| 39 |
+
when (view?.id) {
|
| 40 |
+
R.id.txt_day -> {
|
| 41 |
+
isChecked = !isChecked
|
| 42 |
+
updateBackground()
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
fun updateBackground() {
|
| 48 |
+
if (isChecked) {
|
| 49 |
+
txtDay.background = resources.getDrawable(R.drawable.bg_circle_button_schedule_alarm_day_selected)
|
| 50 |
+
} else {
|
| 51 |
+
txtDay.background = resources.getDrawable(R.drawable.bg_circle_button_schedule_alarm_day)
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/alarm/ScheduleAlarmWidget.kt
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.ui.chat.view.widgets.chatwidget.alarm
|
| 2 |
+
|
| 3 |
+
import android.content.Context
|
| 4 |
+
import android.util.AttributeSet
|
| 5 |
+
import android.view.View
|
| 6 |
+
import android.view.ViewGroup
|
| 7 |
+
import android.widget.LinearLayout
|
| 8 |
+
import android.widget.TimePicker
|
| 9 |
+
import androidx.constraintlayout.widget.ConstraintLayout
|
| 10 |
+
import com.google.android.material.textfield.TextInputLayout
|
| 11 |
+
import com.matthaigh27.chatgptwrapper.R
|
| 12 |
+
import com.matthaigh27.chatgptwrapper.data.models.common.Time
|
| 13 |
+
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 14 |
+
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.OnHideListener
|
| 15 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.AlarmHelper
|
| 16 |
+
|
| 17 |
+
class ScheduleAlarmWidget(
|
| 18 |
+
context: Context,
|
| 19 |
+
time: Time? = null,
|
| 20 |
+
label: String? = null,
|
| 21 |
+
repeat: BooleanArray? = null,
|
| 22 |
+
attrs: AttributeSet? = null
|
| 23 |
+
) : ConstraintLayout(context, attrs), View.OnClickListener {
|
| 24 |
+
|
| 25 |
+
private val WEEK_DAY_COUNT = 7
|
| 26 |
+
private val dayOfWeek = arrayOf(
|
| 27 |
+
"S", "M", "T", "W", "T", "F", "S"
|
| 28 |
+
)
|
| 29 |
+
private val selectedDayList: BooleanArray = BooleanArray(WEEK_DAY_COUNT) { false }
|
| 30 |
+
private val dayItemList: ArrayList<DayOfWeekItem> = ArrayList()
|
| 31 |
+
|
| 32 |
+
private val context: Context
|
| 33 |
+
private var repeat: BooleanArray? = null
|
| 34 |
+
private var llRpeat: LinearLayout
|
| 35 |
+
private var txtLabel: TextInputLayout
|
| 36 |
+
private var timePicker: TimePicker
|
| 37 |
+
|
| 38 |
+
var callback: ChatMessageInterface? = null
|
| 39 |
+
var hideListener: OnHideListener? = null
|
| 40 |
+
|
| 41 |
+
init {
|
| 42 |
+
inflate(context, R.layout.widget_schedule_alarm, this)
|
| 43 |
+
this.context = context
|
| 44 |
+
this.repeat = repeat
|
| 45 |
+
|
| 46 |
+
layoutParams = LayoutParams(
|
| 47 |
+
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
findViewById<View>(R.id.btn_ok).setOnClickListener(this)
|
| 51 |
+
findViewById<View>(R.id.btn_cancel).setOnClickListener(this)
|
| 52 |
+
|
| 53 |
+
llRpeat = findViewById(R.id.ll_repeat)
|
| 54 |
+
txtLabel = findViewById(R.id.txt_label)
|
| 55 |
+
if (label != null) {
|
| 56 |
+
txtLabel.editText!!.setText(label)
|
| 57 |
+
}
|
| 58 |
+
timePicker = findViewById(R.id.time_picker)
|
| 59 |
+
if (time != null) {
|
| 60 |
+
timePicker.hour = time.hour
|
| 61 |
+
timePicker.minute = time.minute
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
initRepeatSetting()
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
private fun initRepeatSetting() {
|
| 68 |
+
dayOfWeek.forEachIndexed { index, day ->
|
| 69 |
+
val item = DayOfWeekItem(context, day)
|
| 70 |
+
item.setOnClickListener {
|
| 71 |
+
selectedDayList[index] = !selectedDayList[index]
|
| 72 |
+
}
|
| 73 |
+
dayItemList.add(item)
|
| 74 |
+
llRpeat.addView(item)
|
| 75 |
+
}
|
| 76 |
+
if (repeat != null) {
|
| 77 |
+
setSelectedDay(repeat!!)
|
| 78 |
+
}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
private fun setSelectedDay(list: BooleanArray) {
|
| 82 |
+
list.forEachIndexed { index, status ->
|
| 83 |
+
dayItemList[index].isChecked = status
|
| 84 |
+
dayItemList[index].updateBackground()
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
override fun onClick(view: View?) {
|
| 89 |
+
when (view?.id) {
|
| 90 |
+
R.id.btn_ok -> {
|
| 91 |
+
AlarmHelper.createAlarm(
|
| 92 |
+
context,
|
| 93 |
+
timePicker.hour,
|
| 94 |
+
timePicker.minute,
|
| 95 |
+
txtLabel.editText?.text.toString()
|
| 96 |
+
)
|
| 97 |
+
callback?.setAlarm(
|
| 98 |
+
timePicker.hour,
|
| 99 |
+
timePicker.minute,
|
| 100 |
+
txtLabel.editText?.text.toString()
|
| 101 |
+
)
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
R.id.btn_cancel -> {
|
| 105 |
+
callback?.cancelAlarm()
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
hideListener?.hide()
|
| 109 |
+
}
|
| 110 |
+
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/contact/ContactDetailWidget.kt
CHANGED
|
@@ -11,7 +11,7 @@ import android.widget.TextView
|
|
| 11 |
import com.bumptech.glide.Glide
|
| 12 |
import com.google.android.material.bottomsheet.BottomSheetDialog
|
| 13 |
import com.matthaigh27.chatgptwrapper.R
|
| 14 |
-
import com.matthaigh27.chatgptwrapper.data.models.ContactModel
|
| 15 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 16 |
|
| 17 |
class ContactDetailWidget(
|
|
@@ -39,22 +39,24 @@ class ContactDetailWidget(
|
|
| 39 |
llPhones = findViewById(R.id.ll_contacts)
|
| 40 |
|
| 41 |
llPhones?.removeAllViews()
|
| 42 |
-
txtDisplayName?.text = contactModel.
|
| 43 |
-
contactModel.
|
| 44 |
-
val contactDetailItem = ContactDetailItem(context)
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
| 52 |
llPhones?.addView(contactDetailItem)
|
| 53 |
}
|
| 54 |
|
| 55 |
btnEditContact?.setOnClickListener(this)
|
| 56 |
imgAvatar = findViewById(R.id.img_avatar)
|
| 57 |
-
imgAvatar?.setContactAvatar(contactModel.
|
| 58 |
}
|
| 59 |
|
| 60 |
private fun ImageView.setContactAvatar(contactId: Long) {
|
|
@@ -73,7 +75,7 @@ class ContactDetailWidget(
|
|
| 73 |
override fun onClick(view: View?) {
|
| 74 |
when (view!!.id) {
|
| 75 |
R.id.btn_edit_contact -> {
|
| 76 |
-
goToContactEditor(contactModel.
|
| 77 |
}
|
| 78 |
|
| 79 |
R.id.btn_send_message -> {
|
|
|
|
| 11 |
import com.bumptech.glide.Glide
|
| 12 |
import com.google.android.material.bottomsheet.BottomSheetDialog
|
| 13 |
import com.matthaigh27.chatgptwrapper.R
|
| 14 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.ContactModel
|
| 15 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 16 |
|
| 17 |
class ContactDetailWidget(
|
|
|
|
| 39 |
llPhones = findViewById(R.id.ll_contacts)
|
| 40 |
|
| 41 |
llPhones?.removeAllViews()
|
| 42 |
+
txtDisplayName?.text = contactModel.displayName
|
| 43 |
+
contactModel.phoneNumbers.forEach { phoneNumber ->
|
| 44 |
+
val contactDetailItem = ContactDetailItem(context).apply {
|
| 45 |
+
this.callback = callback
|
| 46 |
+
this.setContactDetailItemInfo(phoneNumber, contactModel.displayName)
|
| 47 |
+
this.setVisibilityListener(object :
|
| 48 |
+
ContactDetailItem.OnContactDetailVisibilityListener {
|
| 49 |
+
override fun invisible() {
|
| 50 |
+
this@ContactDetailWidget.dismiss()
|
| 51 |
+
}
|
| 52 |
+
})
|
| 53 |
+
}
|
| 54 |
llPhones?.addView(contactDetailItem)
|
| 55 |
}
|
| 56 |
|
| 57 |
btnEditContact?.setOnClickListener(this)
|
| 58 |
imgAvatar = findViewById(R.id.img_avatar)
|
| 59 |
+
imgAvatar?.setContactAvatar(contactModel.contactId.toLong())
|
| 60 |
}
|
| 61 |
|
| 62 |
private fun ImageView.setContactAvatar(contactId: Long) {
|
|
|
|
| 75 |
override fun onClick(view: View?) {
|
| 76 |
when (view!!.id) {
|
| 77 |
R.id.btn_edit_contact -> {
|
| 78 |
+
goToContactEditor(contactModel.contactId)
|
| 79 |
}
|
| 80 |
|
| 81 |
R.id.btn_send_message -> {
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/contact/SearchContactWidget.kt
CHANGED
|
@@ -10,12 +10,12 @@ import android.widget.TextView
|
|
| 10 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 11 |
import com.bumptech.glide.Glide
|
| 12 |
import com.matthaigh27.chatgptwrapper.R
|
| 13 |
-
import com.matthaigh27.chatgptwrapper.data.models.ContactModel
|
| 14 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 15 |
import de.hdodenhof.circleimageview.CircleImageView
|
| 16 |
|
| 17 |
class SearchContactWidget(
|
| 18 |
-
context: Context, cotactModel: ContactModel, attrs: AttributeSet?
|
| 19 |
) : ConstraintLayout(context, attrs), View.OnClickListener {
|
| 20 |
|
| 21 |
private var context: Context
|
|
@@ -38,8 +38,8 @@ class SearchContactWidget(
|
|
| 38 |
civInfoAvatar = findViewById(R.id.civ_avatar)
|
| 39 |
txtInfoName = findViewById(R.id.txt_info_name)
|
| 40 |
|
| 41 |
-
txtInfoName.text = contactModel.
|
| 42 |
-
civInfoAvatar.setContactAvatar(context, contactModel.
|
| 43 |
|
| 44 |
this.setOnClickListener(this)
|
| 45 |
}
|
|
@@ -59,7 +59,9 @@ class SearchContactWidget(
|
|
| 59 |
|
| 60 |
|
| 61 |
private fun showContactDetailView() {
|
| 62 |
-
val bottomSheetDialog = ContactDetailWidget(context, contactModel)
|
|
|
|
|
|
|
| 63 |
bottomSheetDialog.show()
|
| 64 |
}
|
| 65 |
|
|
|
|
| 10 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 11 |
import com.bumptech.glide.Glide
|
| 12 |
import com.matthaigh27.chatgptwrapper.R
|
| 13 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.ContactModel
|
| 14 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 15 |
import de.hdodenhof.circleimageview.CircleImageView
|
| 16 |
|
| 17 |
class SearchContactWidget(
|
| 18 |
+
context: Context, cotactModel: ContactModel, attrs: AttributeSet? = null
|
| 19 |
) : ConstraintLayout(context, attrs), View.OnClickListener {
|
| 20 |
|
| 21 |
private var context: Context
|
|
|
|
| 38 |
civInfoAvatar = findViewById(R.id.civ_avatar)
|
| 39 |
txtInfoName = findViewById(R.id.txt_info_name)
|
| 40 |
|
| 41 |
+
txtInfoName.text = contactModel.displayName
|
| 42 |
+
civInfoAvatar.setContactAvatar(context, contactModel.contactId.toLong())
|
| 43 |
|
| 44 |
this.setOnClickListener(this)
|
| 45 |
}
|
|
|
|
| 59 |
|
| 60 |
|
| 61 |
private fun showContactDetailView() {
|
| 62 |
+
val bottomSheetDialog = ContactDetailWidget(context, contactModel).apply {
|
| 63 |
+
this.callback = callback
|
| 64 |
+
}
|
| 65 |
bottomSheetDialog.show()
|
| 66 |
}
|
| 67 |
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/chatwidget/helpprompt/HelpPromptWidget.kt
CHANGED
|
@@ -10,8 +10,9 @@ import android.widget.LinearLayout
|
|
| 10 |
import android.widget.TextView
|
| 11 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 12 |
import com.matthaigh27.chatgptwrapper.R
|
| 13 |
-
import com.matthaigh27.chatgptwrapper.data.models.HelpPromptModel
|
| 14 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
|
|
|
| 15 |
|
| 16 |
class HelpPromptWidget(context: Context, model: HelpPromptModel) : ConstraintLayout(context),
|
| 17 |
View.OnClickListener {
|
|
@@ -21,7 +22,7 @@ class HelpPromptWidget(context: Context, model: HelpPromptModel) : ConstraintLay
|
|
| 21 |
private var promptEditTextList: ArrayList<EditText>? = null
|
| 22 |
private val promptModel: HelpPromptModel
|
| 23 |
var callback: ChatMessageInterface? = null
|
| 24 |
-
|
| 25 |
|
| 26 |
init {
|
| 27 |
promptModel = model
|
|
@@ -70,6 +71,7 @@ class HelpPromptWidget(context: Context, model: HelpPromptModel) : ConstraintLay
|
|
| 70 |
callback?.canceledHelpPrompt()
|
| 71 |
}
|
| 72 |
}
|
|
|
|
| 73 |
}
|
| 74 |
|
| 75 |
private fun outputCompletePrompt() {
|
|
|
|
| 10 |
import android.widget.TextView
|
| 11 |
import androidx.constraintlayout.widget.ConstraintLayout
|
| 12 |
import com.matthaigh27.chatgptwrapper.R
|
| 13 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpPromptModel
|
| 14 |
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.ChatMessageInterface
|
| 15 |
+
import com.matthaigh27.chatgptwrapper.ui.chat.view.interfaces.OnHideListener
|
| 16 |
|
| 17 |
class HelpPromptWidget(context: Context, model: HelpPromptModel) : ConstraintLayout(context),
|
| 18 |
View.OnClickListener {
|
|
|
|
| 22 |
private var promptEditTextList: ArrayList<EditText>? = null
|
| 23 |
private val promptModel: HelpPromptModel
|
| 24 |
var callback: ChatMessageInterface? = null
|
| 25 |
+
var hideListener: OnHideListener? = null
|
| 26 |
|
| 27 |
init {
|
| 28 |
promptModel = model
|
|
|
|
| 71 |
callback?.canceledHelpPrompt()
|
| 72 |
}
|
| 73 |
}
|
| 74 |
+
hideListener?.hide()
|
| 75 |
}
|
| 76 |
|
| 77 |
private fun outputCompletePrompt() {
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/view/widgets/toolbar/ChatToolsWidget.kt
CHANGED
|
@@ -95,7 +95,7 @@ class ChatToolsWidget(context: Context, parentActivity: Activity, attrs: Attribu
|
|
| 95 |
}
|
| 96 |
|
| 97 |
override fun onFailed(exception: Exception) {
|
| 98 |
-
|
| 99 |
}
|
| 100 |
})
|
| 101 |
}
|
|
|
|
| 95 |
}
|
| 96 |
|
| 97 |
override fun onFailed(exception: Exception) {
|
| 98 |
+
callback?.pickImage(false)
|
| 99 |
}
|
| 100 |
})
|
| 101 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/ui/chat/viewmodel/ChatViewModel.kt
CHANGED
|
@@ -1,15 +1,34 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.ui.chat.viewmodel
|
| 2 |
|
|
|
|
| 3 |
import androidx.lifecycle.MutableLiveData
|
| 4 |
import androidx.lifecycle.ViewModel
|
| 5 |
-
import com.matthaigh27.chatgptwrapper.RisingApplication
|
|
|
|
| 6 |
import com.matthaigh27.chatgptwrapper.data.remote.ApiResource
|
|
|
|
| 7 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.NotificationApiRequest
|
|
|
|
|
|
|
| 8 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
|
|
|
| 9 |
import com.matthaigh27.chatgptwrapper.data.repository.FirebaseRepository
|
| 10 |
import com.matthaigh27.chatgptwrapper.data.repository.RemoteRepository
|
| 11 |
-
import com.matthaigh27.chatgptwrapper.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
import com.matthaigh27.chatgptwrapper.utils.helpers.network.RequestFactory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
class ChatViewModel : ViewModel() {
|
| 15 |
|
|
@@ -28,22 +47,17 @@ class ChatViewModel : ViewModel() {
|
|
| 28 |
|
| 29 |
fun sendNotification(message: String): MutableLiveData<ApiResource<ApiResponse>> {
|
| 30 |
val request = NotificationApiRequest(
|
| 31 |
-
message = message,
|
| 32 |
-
confs = RequestFactory.buildApiKeys()
|
| 33 |
)
|
| 34 |
|
| 35 |
val resource: MutableLiveData<ApiResource<ApiResponse>> = MutableLiveData()
|
| 36 |
resource.value = ApiResource.Loading()
|
| 37 |
|
| 38 |
-
RemoteRepository.sendNotification(
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
onFailure = { throwable ->
|
| 44 |
-
resource.value = ApiResource.Error(throwable)
|
| 45 |
-
}
|
| 46 |
-
)
|
| 47 |
|
| 48 |
return resource
|
| 49 |
}
|
|
@@ -52,25 +66,158 @@ class ChatViewModel : ViewModel() {
|
|
| 52 |
val resource: MutableLiveData<ApiResource<ByteArray>> = MutableLiveData()
|
| 53 |
resource.value = ApiResource.Loading()
|
| 54 |
|
| 55 |
-
FirebaseRepository.downloadImageWithName(
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
onFailure = { throwable ->
|
| 61 |
-
resource.value = ApiResource.Error(throwable)
|
| 62 |
-
}
|
| 63 |
-
)
|
| 64 |
|
| 65 |
return resource
|
| 66 |
}
|
| 67 |
|
| 68 |
-
fun
|
| 69 |
-
val
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
}
|
| 72 |
|
| 73 |
-
fun
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
}
|
| 76 |
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.ui.chat.viewmodel
|
| 2 |
|
| 3 |
+
import android.util.Log
|
| 4 |
import androidx.lifecycle.MutableLiveData
|
| 5 |
import androidx.lifecycle.ViewModel
|
| 6 |
+
import com.matthaigh27.chatgptwrapper.RisingApplication.Companion.appContext
|
| 7 |
+
import com.matthaigh27.chatgptwrapper.data.local.entity.ImageEntity
|
| 8 |
import com.matthaigh27.chatgptwrapper.data.remote.ApiResource
|
| 9 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.ImageRelatednessApiRequest
|
| 10 |
import com.matthaigh27.chatgptwrapper.data.remote.requests.NotificationApiRequest
|
| 11 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.TrainContactsApiRequest
|
| 12 |
+
import com.matthaigh27.chatgptwrapper.data.remote.requests.TrainImageApiRequest
|
| 13 |
import com.matthaigh27.chatgptwrapper.data.remote.responses.ApiResponse
|
| 14 |
+
import com.matthaigh27.chatgptwrapper.data.remote.responses.EmptyResultApiResponse
|
| 15 |
import com.matthaigh27.chatgptwrapper.data.repository.FirebaseRepository
|
| 16 |
import com.matthaigh27.chatgptwrapper.data.repository.RemoteRepository
|
| 17 |
+
import com.matthaigh27.chatgptwrapper.data.repository.RoomRepository
|
| 18 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ContactHelper.getChangedContacts
|
| 19 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ContactHelper.getContacts
|
| 20 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ImageHelper.getBytesFromPath
|
| 21 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ImageHelper.getImagesFromExternalStorage
|
| 22 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.ImageHelper.getLocalPathFromUri
|
| 23 |
import com.matthaigh27.chatgptwrapper.utils.helpers.network.RequestFactory
|
| 24 |
+
import com.matthaigh27.chatgptwrapper.utils.helpers.network.RequestFactory.buildApiKeys
|
| 25 |
+
import kotlinx.coroutines.CoroutineScope
|
| 26 |
+
import kotlinx.coroutines.Deferred
|
| 27 |
+
import kotlinx.coroutines.Dispatchers
|
| 28 |
+
import kotlinx.coroutines.async
|
| 29 |
+
import kotlinx.coroutines.awaitAll
|
| 30 |
+
import kotlinx.coroutines.launch
|
| 31 |
+
import kotlinx.coroutines.withContext
|
| 32 |
|
| 33 |
class ChatViewModel : ViewModel() {
|
| 34 |
|
|
|
|
| 47 |
|
| 48 |
fun sendNotification(message: String): MutableLiveData<ApiResource<ApiResponse>> {
|
| 49 |
val request = NotificationApiRequest(
|
| 50 |
+
message = message, confs = RequestFactory.buildApiKeys()
|
|
|
|
| 51 |
)
|
| 52 |
|
| 53 |
val resource: MutableLiveData<ApiResource<ApiResponse>> = MutableLiveData()
|
| 54 |
resource.value = ApiResource.Loading()
|
| 55 |
|
| 56 |
+
RemoteRepository.sendNotification(request, onSuccess = { apiResponse ->
|
| 57 |
+
resource.value = ApiResource.Success(apiResponse)
|
| 58 |
+
}, onFailure = { throwable ->
|
| 59 |
+
resource.value = ApiResource.Error(throwable)
|
| 60 |
+
})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
|
| 62 |
return resource
|
| 63 |
}
|
|
|
|
| 66 |
val resource: MutableLiveData<ApiResource<ByteArray>> = MutableLiveData()
|
| 67 |
resource.value = ApiResource.Loading()
|
| 68 |
|
| 69 |
+
FirebaseRepository.downloadImageWithName(name, onSuccess = { apiResponse ->
|
| 70 |
+
resource.value = ApiResource.Success(apiResponse)
|
| 71 |
+
}, onFailure = { throwable ->
|
| 72 |
+
resource.value = ApiResource.Error(throwable)
|
| 73 |
+
})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
return resource
|
| 76 |
}
|
| 77 |
|
| 78 |
+
fun uploadImageToFirebase(imageByteArray: ByteArray): MutableLiveData<ApiResource<String>> {
|
| 79 |
+
val resource: MutableLiveData<ApiResource<String>> = MutableLiveData()
|
| 80 |
+
resource.value = ApiResource.Loading()
|
| 81 |
+
|
| 82 |
+
FirebaseRepository.uploadImageAsync(imageByteArray, onSuccess = { apiResponse ->
|
| 83 |
+
resource.value = ApiResource.Success(apiResponse)
|
| 84 |
+
}, onFailure = { throwable ->
|
| 85 |
+
resource.value = ApiResource.Error(throwable)
|
| 86 |
+
})
|
| 87 |
+
|
| 88 |
+
return resource
|
| 89 |
}
|
| 90 |
|
| 91 |
+
fun trainImages(): MutableLiveData<Boolean> {
|
| 92 |
+
val state: MutableLiveData<Boolean> = MutableLiveData()
|
| 93 |
+
state.value = true
|
| 94 |
+
CoroutineScope(Dispatchers.IO).launch {
|
| 95 |
+
val images = getImagesFromExternalStorage(appContext.contentResolver)
|
| 96 |
+
val originalImages = RoomRepository.getAllImages().value
|
| 97 |
|
| 98 |
+
val existImageStatus = BooleanArray(originalImages!!.size) { false }
|
| 99 |
+
val tasks = mutableListOf<Deferred<Unit>>()
|
| 100 |
+
|
| 101 |
+
Log.d("Brain", "Start")
|
| 102 |
+
images.forEach { image ->
|
| 103 |
+
var isExist = false
|
| 104 |
+
val path = getLocalPathFromUri(appContext, image.uri)
|
| 105 |
+
for (i in originalImages.indices) {
|
| 106 |
+
val entity: ImageEntity = originalImages[i]
|
| 107 |
+
if (entity.path == path) {
|
| 108 |
+
if (entity.dataModified != image.modifiedDate) {
|
| 109 |
+
val byteArray = getBytesFromPath(path)
|
| 110 |
+
val task = async {
|
| 111 |
+
val uuid = FirebaseRepository.uploadImage(byteArray)
|
| 112 |
+
if (uuid != "Error") {
|
| 113 |
+
RoomRepository.updateImage(
|
| 114 |
+
ImageEntity(
|
| 115 |
+
id = 0,
|
| 116 |
+
path = path,
|
| 117 |
+
name = uuid,
|
| 118 |
+
dataModified = image.modifiedDate
|
| 119 |
+
)
|
| 120 |
+
)
|
| 121 |
+
RemoteRepository.trainImage(
|
| 122 |
+
TrainImageApiRequest(
|
| 123 |
+
uuid, "updated", buildApiKeys()
|
| 124 |
+
)
|
| 125 |
+
)
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
tasks.add(task)
|
| 129 |
+
}
|
| 130 |
+
isExist = true
|
| 131 |
+
existImageStatus[i] = true
|
| 132 |
+
break
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
if (!isExist) {
|
| 136 |
+
path?.let {
|
| 137 |
+
val byteArray = getBytesFromPath(it)
|
| 138 |
+
val task = async {
|
| 139 |
+
val uuid = FirebaseRepository.uploadImage(byteArray)
|
| 140 |
+
if (uuid != "Error") {
|
| 141 |
+
RoomRepository.insertImage(
|
| 142 |
+
ImageEntity(
|
| 143 |
+
id = 0,
|
| 144 |
+
path = path,
|
| 145 |
+
name = uuid,
|
| 146 |
+
dataModified = image.modifiedDate
|
| 147 |
+
)
|
| 148 |
+
)
|
| 149 |
+
RemoteRepository.trainImage(
|
| 150 |
+
TrainImageApiRequest(
|
| 151 |
+
uuid, "created", buildApiKeys()
|
| 152 |
+
)
|
| 153 |
+
)
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
tasks.add(task)
|
| 157 |
+
}
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
for (i in existImageStatus.indices) {
|
| 162 |
+
if (!existImageStatus[i]) {
|
| 163 |
+
val task = async {
|
| 164 |
+
RoomRepository.deleteImage(
|
| 165 |
+
ImageEntity(
|
| 166 |
+
originalImages[i].id, "", "", 0L
|
| 167 |
+
)
|
| 168 |
+
)
|
| 169 |
+
val result = RemoteRepository.trainImage(
|
| 170 |
+
TrainImageApiRequest(
|
| 171 |
+
originalImages[i].name, "deleted", buildApiKeys()
|
| 172 |
+
)
|
| 173 |
+
)
|
| 174 |
+
}
|
| 175 |
+
tasks.add(task)
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
tasks.awaitAll()
|
| 180 |
+
Log.d("Brain", "Finish")
|
| 181 |
+
withContext(Dispatchers.Main) {
|
| 182 |
+
state.value = false
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
return state
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
fun trainContacts(): MutableLiveData<Boolean> {
|
| 189 |
+
val state: MutableLiveData<Boolean> = MutableLiveData()
|
| 190 |
+
state.value = true
|
| 191 |
+
val contacts = getContacts(appContext)
|
| 192 |
+
CoroutineScope(Dispatchers.Main).launch {
|
| 193 |
+
val resource: MutableLiveData<ApiResource<EmptyResultApiResponse>> = MutableLiveData()
|
| 194 |
+
val changedContacts = getChangedContacts(contacts)
|
| 195 |
+
val request = TrainContactsApiRequest(changedContacts, RequestFactory.buildApiKeys())
|
| 196 |
+
RemoteRepository.trainContacts(request, onSuccess = { apiResponse ->
|
| 197 |
+
resource.value = ApiResource.Success(apiResponse)
|
| 198 |
+
}, onFailure = { throwable ->
|
| 199 |
+
resource.value = ApiResource.Error(throwable)
|
| 200 |
+
})
|
| 201 |
+
withContext(Dispatchers.Main) {
|
| 202 |
+
state.value = false
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
return state
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
fun getImageRelatedness(imageName: String, message: String): MutableLiveData<ApiResource<ApiResponse>> {
|
| 209 |
+
val resource: MutableLiveData<ApiResource<ApiResponse>> = MutableLiveData()
|
| 210 |
+
val request = ImageRelatednessApiRequest(
|
| 211 |
+
image_name = imageName, message = message, confs = buildApiKeys()
|
| 212 |
+
)
|
| 213 |
+
resource.value = ApiResource.Loading()
|
| 214 |
+
|
| 215 |
+
RemoteRepository.getImageRelatedness(request, onSuccess = { apiResponse ->
|
| 216 |
+
resource.value = ApiResource.Success(apiResponse)
|
| 217 |
+
}, onFailure = { throwable ->
|
| 218 |
+
resource.value = ApiResource.Error(throwable)
|
| 219 |
+
})
|
| 220 |
+
|
| 221 |
+
return resource
|
| 222 |
}
|
| 223 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/Constants.kt
CHANGED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils
|
| 2 |
|
|
|
|
|
|
|
| 3 |
object Constants {
|
| 4 |
-
val API_BASE_URL =
|
| 5 |
|
| 6 |
val TYPE_RESPONSE_MESSAGE = "message"
|
| 7 |
val TYPE_RESPONSE_BROWSER = "browser"
|
|
@@ -10,12 +12,14 @@ object Constants {
|
|
| 10 |
val TYPE_RESPONSE_IMAGE = "image"
|
| 11 |
val TYPE_RESPONSE_HELP_COMMAND = "help_command"
|
| 12 |
val TYPE_RESPONSE_SMS = "sms"
|
|
|
|
| 13 |
val TYPE_RESPONSE_CONTACT = "contact"
|
| 14 |
|
| 15 |
val TYPE_WIDGET_SMS = "sms"
|
| 16 |
val TYPE_WIDGET_HELP_PROMPT = "help_prompt"
|
| 17 |
val TYPE_WIDGET_FEEDBACK = "feedback"
|
| 18 |
val TYPE_WIDGET_SEARCH_CONTACT = "search_contact"
|
|
|
|
| 19 |
|
| 20 |
val HELP_COMMAND_ERROR_NO_MAIN = "no main command"
|
| 21 |
val HELP_COMMAND_ERROR_NO_INVALID_FORMAT = "Invalid Command Format"
|
|
@@ -31,4 +35,11 @@ object Constants {
|
|
| 31 |
val FIELD_HELP_PROMPT_PROMPT = "prompt"
|
| 32 |
val FIELD_HELP_PROMPT_DESCRIPTION = "description"
|
| 33 |
val FIELD_HELP_PROMPT_TAGS = "tags"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils
|
| 2 |
|
| 3 |
+
import com.matthaigh27.chatgptwrapper.BuildConfig
|
| 4 |
+
|
| 5 |
object Constants {
|
| 6 |
+
val API_BASE_URL = BuildConfig.BASE_URL
|
| 7 |
|
| 8 |
val TYPE_RESPONSE_MESSAGE = "message"
|
| 9 |
val TYPE_RESPONSE_BROWSER = "browser"
|
|
|
|
| 12 |
val TYPE_RESPONSE_IMAGE = "image"
|
| 13 |
val TYPE_RESPONSE_HELP_COMMAND = "help_command"
|
| 14 |
val TYPE_RESPONSE_SMS = "sms"
|
| 15 |
+
val TYPE_RESPONSE_ALARM = "alarm"
|
| 16 |
val TYPE_RESPONSE_CONTACT = "contact"
|
| 17 |
|
| 18 |
val TYPE_WIDGET_SMS = "sms"
|
| 19 |
val TYPE_WIDGET_HELP_PROMPT = "help_prompt"
|
| 20 |
val TYPE_WIDGET_FEEDBACK = "feedback"
|
| 21 |
val TYPE_WIDGET_SEARCH_CONTACT = "search_contact"
|
| 22 |
+
val TYPE_WIDGET_SCHEDULE_ALARM = "schedule_alarm"
|
| 23 |
|
| 24 |
val HELP_COMMAND_ERROR_NO_MAIN = "no main command"
|
| 25 |
val HELP_COMMAND_ERROR_NO_INVALID_FORMAT = "Invalid Command Format"
|
|
|
|
| 35 |
val FIELD_HELP_PROMPT_PROMPT = "prompt"
|
| 36 |
val FIELD_HELP_PROMPT_DESCRIPTION = "description"
|
| 37 |
val FIELD_HELP_PROMPT_TAGS = "tags"
|
| 38 |
+
|
| 39 |
+
val PROPS_WIDGET_DESC = "widget description"
|
| 40 |
+
|
| 41 |
+
val TIME_OUT_CALL = 60L
|
| 42 |
+
val TIME_OUT_CONNECT = 60L
|
| 43 |
+
val TIME_OUT_READ = 60L
|
| 44 |
+
val TIME_OUT_WRITE = 60L
|
| 45 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/CallbackTypes.kt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.utils.helpers
|
| 2 |
+
|
| 3 |
+
typealias OnSuccess<T> = (T) -> Unit
|
| 4 |
+
typealias OnFailure<T> = (T) -> Unit
|
| 5 |
+
|
| 6 |
+
typealias OnHide = () -> Unit
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/Converter.kt
CHANGED
|
@@ -1,8 +1,9 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers
|
| 2 |
|
| 3 |
-
import com.
|
|
|
|
|
|
|
| 4 |
import com.matthaigh27.chatgptwrapper.utils.Constants
|
| 5 |
-
import com.matthaigh27.chatgptwrapper.utils.helpers.chat.CommandHelper
|
| 6 |
import org.json.JSONArray
|
| 7 |
import org.json.JSONException
|
| 8 |
import org.json.JSONObject
|
|
@@ -18,7 +19,8 @@ object Converter {
|
|
| 18 |
|
| 19 |
val helpPromptModel = HelpPromptModel()
|
| 20 |
helpPromptModel.name = helpCommand.getString(Constants.FIELD_HELP_PROMPT_NAME)
|
| 21 |
-
helpPromptModel.description =
|
|
|
|
| 22 |
helpPromptModel.prompt = helpCommand.getString(Constants.FIELD_HELP_PROMPT_PROMPT)
|
| 23 |
|
| 24 |
helpPromptModel.tags = ArrayList()
|
|
@@ -34,4 +36,12 @@ object Converter {
|
|
| 34 |
}
|
| 35 |
return promptList
|
| 36 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers
|
| 2 |
|
| 3 |
+
import com.google.gson.Gson
|
| 4 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpPromptModel
|
| 5 |
+
import com.matthaigh27.chatgptwrapper.data.models.common.Time
|
| 6 |
import com.matthaigh27.chatgptwrapper.utils.Constants
|
|
|
|
| 7 |
import org.json.JSONArray
|
| 8 |
import org.json.JSONException
|
| 9 |
import org.json.JSONObject
|
|
|
|
| 19 |
|
| 20 |
val helpPromptModel = HelpPromptModel()
|
| 21 |
helpPromptModel.name = helpCommand.getString(Constants.FIELD_HELP_PROMPT_NAME)
|
| 22 |
+
helpPromptModel.description =
|
| 23 |
+
helpCommand.getString(Constants.FIELD_HELP_PROMPT_DESCRIPTION)
|
| 24 |
helpPromptModel.prompt = helpCommand.getString(Constants.FIELD_HELP_PROMPT_PROMPT)
|
| 25 |
|
| 26 |
helpPromptModel.tags = ArrayList()
|
|
|
|
| 36 |
}
|
| 37 |
return promptList
|
| 38 |
}
|
| 39 |
+
|
| 40 |
+
fun stringToTime(strTime: String): Time {
|
| 41 |
+
val list = strTime.split(':')
|
| 42 |
+
val hour = list[0].toInt()
|
| 43 |
+
val minute = list[1].toInt()
|
| 44 |
+
val time = Time(hour, minute, 0)
|
| 45 |
+
return time
|
| 46 |
+
}
|
| 47 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/AlarmHelper.kt
CHANGED
|
@@ -1,34 +1,74 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers.chat
|
| 2 |
|
|
|
|
|
|
|
| 3 |
import android.content.Context
|
| 4 |
-
import android.
|
| 5 |
-
import android.
|
| 6 |
-
import
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
object AlarmHelper {
|
| 9 |
-
fun
|
| 10 |
-
val
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
}
|
| 29 |
}
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
}
|
| 34 |
-
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers.chat
|
| 2 |
|
| 3 |
+
import android.app.AlarmManager
|
| 4 |
+
import android.app.PendingIntent
|
| 5 |
import android.content.Context
|
| 6 |
+
import android.content.Context.ALARM_SERVICE
|
| 7 |
+
import android.content.Intent
|
| 8 |
+
import android.provider.AlarmClock
|
| 9 |
+
import android.util.Log
|
| 10 |
+
import java.util.Calendar
|
| 11 |
+
|
| 12 |
|
| 13 |
object AlarmHelper {
|
| 14 |
+
fun createAlarm(context: Context, hour: Int, minute: Int, label: String) {
|
| 15 |
+
val calendar = Calendar.getInstance()
|
| 16 |
+
|
| 17 |
+
calendar.set(Calendar.HOUR_OF_DAY, hour)
|
| 18 |
+
calendar.set(Calendar.MINUTE, minute)
|
| 19 |
+
calendar.set(Calendar.SECOND, 0)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
val intent = Intent("android.intent.action.SET_ALARM")
|
| 23 |
+
intent.putExtra("android.intent.extra.alarm.HOUR", hour)
|
| 24 |
+
intent.putExtra("android.intent.extra.alarm.MINUTES", minute)
|
| 25 |
+
intent.putExtra("android.intent.extra.alarm.SKIP_UI", true)
|
| 26 |
+
intent.putExtra("android.intent.extra.alarm.MESSAGE", label)
|
| 27 |
+
|
| 28 |
+
context.startActivity(intent)
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
fun scheduleRepeatingAlarm(context: Context, selectedDays: ArrayList<Int>, hour: Int, minute: Int) {
|
| 32 |
+
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
| 33 |
+
|
| 34 |
+
val alarmIntent = Intent(context, AlarmReceiver::class.java)
|
| 35 |
+
alarmIntent.action = "com.matthaigh27.chatgptwrapper"
|
| 36 |
+
|
| 37 |
+
val pendingIntent = PendingIntent.getBroadcast(
|
| 38 |
+
context,
|
| 39 |
+
0,
|
| 40 |
+
alarmIntent,
|
| 41 |
+
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
// Calculate the time difference between the next alarm time and now.
|
| 45 |
+
val calendar = Calendar.getInstance()
|
| 46 |
+
val timeNow = calendar.timeInMillis
|
| 47 |
+
var minTimeDiff = Long.MAX_VALUE
|
| 48 |
+
|
| 49 |
+
for (dayOfWeek in selectedDays) {
|
| 50 |
+
calendar.set(Calendar.HOUR_OF_DAY, hour)
|
| 51 |
+
calendar.set(Calendar.MINUTE, minute)
|
| 52 |
+
calendar.set(Calendar.SECOND, 0)
|
| 53 |
+
calendar.set(Calendar.MILLISECOND, 0)
|
| 54 |
+
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek)
|
| 55 |
+
|
| 56 |
+
var alarmTime = calendar.timeInMillis
|
| 57 |
+
if (alarmTime < timeNow) { // If the alarm time is in the past, set it for the next week.
|
| 58 |
+
alarmTime += AlarmManager.INTERVAL_DAY * 7
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
val timeDiff = alarmTime - timeNow
|
| 62 |
+
if (timeDiff < minTimeDiff) {
|
| 63 |
+
minTimeDiff = timeDiff
|
| 64 |
}
|
| 65 |
}
|
| 66 |
|
| 67 |
+
alarmManager.setInexactRepeating(
|
| 68 |
+
AlarmManager.RTC_WAKEUP,
|
| 69 |
+
timeNow + minTimeDiff,
|
| 70 |
+
AlarmManager.INTERVAL_DAY * 7, // Set to repeat every week.
|
| 71 |
+
pendingIntent
|
| 72 |
+
)
|
| 73 |
}
|
| 74 |
+
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/AlarmReceiver.kt
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.matthaigh27.chatgptwrapper.utils.helpers.chat
|
| 2 |
+
|
| 3 |
+
import android.content.BroadcastReceiver
|
| 4 |
+
import android.content.Context
|
| 5 |
+
import android.content.Intent
|
| 6 |
+
import android.util.Log
|
| 7 |
+
|
| 8 |
+
class AlarmReceiver : BroadcastReceiver() {
|
| 9 |
+
override fun onReceive(context: Context, intent: Intent) {
|
| 10 |
+
val label = intent.getStringExtra("label")
|
| 11 |
+
Log.d("AlarmReceiver", "Alarm triggered. Label: $label")
|
| 12 |
+
}
|
| 13 |
+
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/CommandHelper.kt
CHANGED
|
@@ -1,15 +1,11 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers.chat
|
| 2 |
|
| 3 |
-
import com.matthaigh27.chatgptwrapper.data.models.HelpCommandModel
|
| 4 |
-
import com.matthaigh27.chatgptwrapper.data.models.HelpPromptModel
|
| 5 |
-
import com.matthaigh27.chatgptwrapper.utils.Constants.ERROR_MSG_JSON
|
| 6 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND
|
| 7 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ALL
|
| 8 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ERROR_NO_INVALID_FORMAT
|
| 9 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ERROR_NO_MAIN
|
| 10 |
-
import org.json.JSONArray
|
| 11 |
-
import org.json.JSONException
|
| 12 |
-
import org.json.JSONObject
|
| 13 |
|
| 14 |
object CommandHelper {
|
| 15 |
fun isMainHelpCommand(model: HelpCommandModel): Boolean {
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers.chat
|
| 2 |
|
| 3 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpCommandModel
|
| 4 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.HelpPromptModel
|
|
|
|
| 5 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND
|
| 6 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ALL
|
| 7 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ERROR_NO_INVALID_FORMAT
|
| 8 |
import com.matthaigh27.chatgptwrapper.utils.Constants.HELP_COMMAND_ERROR_NO_MAIN
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
object CommandHelper {
|
| 11 |
fun isMainHelpCommand(model: HelpCommandModel): Boolean {
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/ContactHelper.kt
CHANGED
|
@@ -4,7 +4,12 @@ import android.annotation.SuppressLint
|
|
| 4 |
import android.content.ContentResolver
|
| 5 |
import android.content.Context
|
| 6 |
import android.provider.ContactsContract
|
| 7 |
-
import com.matthaigh27.chatgptwrapper.data.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
object ContactHelper {
|
| 10 |
@SuppressLint("Range")
|
|
@@ -26,8 +31,8 @@ object ContactHelper {
|
|
| 26 |
)).toInt()
|
| 27 |
|
| 28 |
val contact = ContactModel()
|
| 29 |
-
contact.
|
| 30 |
-
contact.
|
| 31 |
|
| 32 |
if (phoneNumber > 0) {
|
| 33 |
val cursorPhone = context.contentResolver.query(
|
|
@@ -43,7 +48,7 @@ object ContactHelper {
|
|
| 43 |
val phoneNumValue = cursorPhone.getString(
|
| 44 |
cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
|
| 45 |
)
|
| 46 |
-
contact.
|
| 47 |
}
|
| 48 |
}
|
| 49 |
cursorPhone.close()
|
|
@@ -55,4 +60,87 @@ object ContactHelper {
|
|
| 55 |
cursor.close()
|
| 56 |
return contacts
|
| 57 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
}
|
|
|
|
| 4 |
import android.content.ContentResolver
|
| 5 |
import android.content.Context
|
| 6 |
import android.provider.ContactsContract
|
| 7 |
+
import com.matthaigh27.chatgptwrapper.data.local.entity.ContactEntity
|
| 8 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.ContactModel
|
| 9 |
+
import com.matthaigh27.chatgptwrapper.data.repository.RoomRepository
|
| 10 |
+
import kotlinx.coroutines.CoroutineScope
|
| 11 |
+
import kotlinx.coroutines.Dispatchers
|
| 12 |
+
import kotlinx.coroutines.async
|
| 13 |
|
| 14 |
object ContactHelper {
|
| 15 |
@SuppressLint("Range")
|
|
|
|
| 31 |
)).toInt()
|
| 32 |
|
| 33 |
val contact = ContactModel()
|
| 34 |
+
contact.contactId = id
|
| 35 |
+
contact.displayName = name
|
| 36 |
|
| 37 |
if (phoneNumber > 0) {
|
| 38 |
val cursorPhone = context.contentResolver.query(
|
|
|
|
| 48 |
val phoneNumValue = cursorPhone.getString(
|
| 49 |
cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
|
| 50 |
)
|
| 51 |
+
contact.phoneNumbers.add(phoneNumValue)
|
| 52 |
}
|
| 53 |
}
|
| 54 |
cursorPhone.close()
|
|
|
|
| 60 |
cursor.close()
|
| 61 |
return contacts
|
| 62 |
}
|
| 63 |
+
|
| 64 |
+
suspend fun getChangedContacts(
|
| 65 |
+
contacts: ArrayList<ContactModel>
|
| 66 |
+
): ArrayList<ContactModel> {
|
| 67 |
+
return CoroutineScope(Dispatchers.IO).async {
|
| 68 |
+
val originalContacts = RoomRepository.getAllContacts().value
|
| 69 |
+
val changedContactList = ArrayList<ContactModel>()
|
| 70 |
+
for (i in originalContacts!!.indices) {
|
| 71 |
+
var isExist = false
|
| 72 |
+
contacts.forEach { contact ->
|
| 73 |
+
if (originalContacts[i].id == contact.contactId) {
|
| 74 |
+
if (originalContacts[i].name != contact.displayName || originalContacts[i].phoneNumber != contact.phoneNumbers.toString()) {
|
| 75 |
+
contact.status = "updated"
|
| 76 |
+
changedContactList.add(contact)
|
| 77 |
+
|
| 78 |
+
try {
|
| 79 |
+
RoomRepository.updateContact(
|
| 80 |
+
ContactEntity(
|
| 81 |
+
contact.contactId,
|
| 82 |
+
contact.displayName,
|
| 83 |
+
contact.phoneNumbers.toString()
|
| 84 |
+
)
|
| 85 |
+
)
|
| 86 |
+
} catch (e: Exception) {
|
| 87 |
+
e.printStackTrace()
|
| 88 |
+
}
|
| 89 |
+
} else {
|
| 90 |
+
contact.status = "nothing"
|
| 91 |
+
}
|
| 92 |
+
isExist = true
|
| 93 |
+
return@forEach
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
if (!isExist) {
|
| 97 |
+
val deletedContacts = ContactModel()
|
| 98 |
+
deletedContacts.contactId = originalContacts[i].id
|
| 99 |
+
deletedContacts.status = "deleted"
|
| 100 |
+
changedContactList.add(deletedContacts)
|
| 101 |
+
|
| 102 |
+
try {
|
| 103 |
+
RoomRepository.deleteContact(
|
| 104 |
+
ContactEntity(
|
| 105 |
+
deletedContacts.contactId,
|
| 106 |
+
deletedContacts.displayName,
|
| 107 |
+
deletedContacts.phoneNumbers.toString()
|
| 108 |
+
)
|
| 109 |
+
)
|
| 110 |
+
} catch (e: Exception) {
|
| 111 |
+
e.printStackTrace()
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
contacts.forEach { contact ->
|
| 116 |
+
if (contact.status.isEmpty()) {
|
| 117 |
+
contact.status = "created"
|
| 118 |
+
changedContactList.add(contact)
|
| 119 |
+
try {
|
| 120 |
+
RoomRepository.insertContact(
|
| 121 |
+
ContactEntity(
|
| 122 |
+
contact.contactId,
|
| 123 |
+
contact.displayName,
|
| 124 |
+
contact.phoneNumbers.toString()
|
| 125 |
+
)
|
| 126 |
+
)
|
| 127 |
+
} catch (e: Exception) {
|
| 128 |
+
e.printStackTrace()
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
changedContactList
|
| 133 |
+
}.await()
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
fun getContactModelById(contactId: String, contacts: ArrayList<ContactModel>): ContactModel {
|
| 137 |
+
var contactModel = ContactModel()
|
| 138 |
+
val searchResults = contacts.filter { contact ->
|
| 139 |
+
contactId == contact.contactId
|
| 140 |
+
}
|
| 141 |
+
if (searchResults.isNotEmpty()) {
|
| 142 |
+
contactModel = searchResults[0]
|
| 143 |
+
}
|
| 144 |
+
return contactModel
|
| 145 |
+
}
|
| 146 |
}
|
Android/app/src/main/java/com/matthaigh27/chatgptwrapper/utils/helpers/chat/ImageHelper.kt
CHANGED
|
@@ -1,6 +1,8 @@
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers.chat
|
| 2 |
|
| 3 |
import android.content.ContentResolver
|
|
|
|
|
|
|
| 4 |
import android.graphics.Bitmap
|
| 5 |
import android.graphics.BitmapFactory
|
| 6 |
import android.graphics.Canvas
|
|
@@ -13,7 +15,7 @@ import android.net.Uri
|
|
| 13 |
import android.os.Environment
|
| 14 |
import android.provider.MediaStore
|
| 15 |
import com.matthaigh27.chatgptwrapper.RisingApplication
|
| 16 |
-
import com.matthaigh27.chatgptwrapper.data.models.ImageModel
|
| 17 |
import java.io.ByteArrayOutputStream
|
| 18 |
import java.io.File
|
| 19 |
import java.io.FileInputStream
|
|
@@ -110,5 +112,16 @@ object ImageHelper {
|
|
| 110 |
return listOfImages
|
| 111 |
}
|
| 112 |
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
}
|
|
|
|
| 1 |
package com.matthaigh27.chatgptwrapper.utils.helpers.chat
|
| 2 |
|
| 3 |
import android.content.ContentResolver
|
| 4 |
+
import android.content.Context
|
| 5 |
+
import android.database.Cursor
|
| 6 |
import android.graphics.Bitmap
|
| 7 |
import android.graphics.BitmapFactory
|
| 8 |
import android.graphics.Canvas
|
|
|
|
| 15 |
import android.os.Environment
|
| 16 |
import android.provider.MediaStore
|
| 17 |
import com.matthaigh27.chatgptwrapper.RisingApplication
|
| 18 |
+
import com.matthaigh27.chatgptwrapper.data.models.chat.ImageModel
|
| 19 |
import java.io.ByteArrayOutputStream
|
| 20 |
import java.io.File
|
| 21 |
import java.io.FileInputStream
|
|
|
|
| 112 |
return listOfImages
|
| 113 |
}
|
| 114 |
|
| 115 |
+
fun getLocalPathFromUri(context: Context, contentUri: Uri?): String? {
|
| 116 |
+
var cursor: Cursor? = null
|
| 117 |
+
return try {
|
| 118 |
+
val proj = arrayOf(MediaStore.Images.Media.DATA)
|
| 119 |
+
cursor = context.contentResolver.query(contentUri!!, proj, null, null, null)
|
| 120 |
+
val column_index: Int = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
|
| 121 |
+
cursor.moveToFirst()
|
| 122 |
+
cursor.getString(column_index)
|
| 123 |
+
} finally {
|
| 124 |
+
cursor?.close()
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
}
|
Android/app/src/main/res/drawable/bg_circle_button_schedule_alarm_day.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
| 3 |
+
android:shape="rectangle">
|
| 4 |
+
<corners android:radius="@dimen/radius_huge" />
|
| 5 |
+
<solid android:color="@color/color_primary_dark" />
|
| 6 |
+
</shape>
|
Android/app/src/main/res/drawable/bg_circle_button_schedule_alarm_day_selected.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
| 3 |
+
android:shape="rectangle">
|
| 4 |
+
<corners android:radius="@dimen/radius_huge" />
|
| 5 |
+
<solid android:color="@color/color_accent" />
|
| 6 |
+
</shape>
|
Android/app/src/main/res/drawable/bg_item_error_message.xml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
| 3 |
+
android:shape="rectangle">
|
| 4 |
+
<solid android:color="@color/bg_color_message_error" />
|
| 5 |
+
<corners
|
| 6 |
+
android:radius="@dimen/radius_normal" />
|
| 7 |
+
</shape>
|
Android/app/src/main/res/layout/item_container_chat_widget.xml
CHANGED
|
@@ -7,4 +7,16 @@
|
|
| 7 |
android:layout_marginTop="@dimen/spacing_tiny"
|
| 8 |
android:padding="@dimen/spacing_tiny">
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
</FrameLayout>
|
|
|
|
| 7 |
android:layout_marginTop="@dimen/spacing_tiny"
|
| 8 |
android:padding="@dimen/spacing_tiny">
|
| 9 |
|
| 10 |
+
<HorizontalScrollView
|
| 11 |
+
android:layout_width="match_parent"
|
| 12 |
+
android:layout_height="wrap_content"
|
| 13 |
+
android:orientation="horizontal">
|
| 14 |
+
<LinearLayout
|
| 15 |
+
android:id="@+id/ll_contacts_widget"
|
| 16 |
+
android:layout_width="match_parent"
|
| 17 |
+
android:layout_height="wrap_content"
|
| 18 |
+
android:orientation="horizontal"
|
| 19 |
+
android:visibility="gone" />
|
| 20 |
+
</HorizontalScrollView>
|
| 21 |
+
|
| 22 |
</FrameLayout>
|