From 5cc40ee0561e97ef3c80122c0486219b382d4e96 Mon Sep 17 00:00:00 2001
From: lunaticbum <>
Date: Thu, 22 Aug 2024 17:51:59 +0900
Subject: [PATCH] ....
---
app/src/main/AndroidManifest.xml | 1 +
.../rasel/lunar/launcher/LauncherActivity.kt | 29 ++--
.../rasel/lunar/launcher/home/LauncherHome.kt | 124 +++++++++++++++++-
.../launcher/todos/MissedCallsAdapter.kt | 113 ++++++++++++++++
app/src/main/res/layout/launcher_home.xml | 44 ++++++-
app/src/main/res/layout/list_item.xml | 2 +-
6 files changed, 295 insertions(+), 18 deletions(-)
create mode 100644 app/src/main/kotlin/rasel/lunar/launcher/todos/MissedCallsAdapter.kt
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0aebb899..026ec983 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,6 +18,7 @@
+
()
+
+ private suspend fun getCallDetails() {
+ MainScope().async {
+ var dateParam = Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 3)).time.toString()
+ val managedCursor = lActivity!!.managedQuery(
+ CallLog.Calls.CONTENT_URI, arrayOf(
+ CallLog.Calls.NUMBER,
+ CallLog.Calls.TYPE,
+ CallLog.Calls.DATE,
+ CallLog.Calls.DURATION,
+ CallLog.Calls.CACHED_NAME,
+ ), CallLog.Calls.DATE + "> ? AND " + CallLog.Calls.TYPE + " > ?", arrayOf(dateParam, "2"), CallLog.Calls.DATE + " desc")
+ val number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER)
+ val type = managedCursor.getColumnIndex(CallLog.Calls.TYPE)
+ val date = managedCursor.getColumnIndex(CallLog.Calls.DATE)
+ val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION)
+ val name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME)
+// sb.append("Call Details : ${managedCursor.count}")
+ var missedCalls = hashMapOf()
+ while (managedCursor.moveToNext()) {
+ val phNumber = managedCursor.getString(number) // mobile number
+ val callType = managedCursor.getString(type) // call type
+ val callDate = managedCursor.getString(date) // call date
+ val callDayTime: Date = Date(callDate.toLong())
+ val callDuration = managedCursor.getString(duration)
+ val callerName = managedCursor.getString(name)
+
+ var dir: String = ""
+ val dircode = callType.toInt()
+ when (dircode) {
+ CallLog.Calls.INCOMING_TYPE -> {
+ dir = "INCOMING_TYPE"
+ }
+ CallLog.Calls.OUTGOING_TYPE -> {
+ dir = "OUTGOING_TYPE"
+ }
+ CallLog.Calls.MISSED_TYPE -> {
+ dir = "MISSED_TYPE"
+ }
+ CallLog.Calls.VOICEMAIL_TYPE -> {
+ dir = "VOICEMAIL_TYPE"
+ }
+ CallLog.Calls.REJECTED_TYPE -> {
+ dir = "REJECTED_TYPE"
+ }
+ CallLog.Calls.BLOCKED_TYPE -> {
+ dir = "BLOCKED_TYPE"
+ }
+ CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> {
+ dir = "ANSWERED_EXTERNALLY_TYPE"
+ }
+ }
+// if (dircode > 2) {
+ var missed: MissedCall = if (missedCalls.containsKey(phNumber)) {
+ missedCalls.get(phNumber)!!.apply {
+ count = count + 1
+ }
+ } else {
+ MissedCall(1,callerName,phNumber, dircode, dir, SimpleDateFormat("yyy/MM/dd-HH:mm:ss").format(callDayTime))
+ }
+ missedCalls.put(phNumber, missed)
+// }
+ }
+
+
+ managedCursor.close()
+ return@async missedCalls
+ }.await().apply {
+ if (callList.size == this.size) {
+
+ } else {
+ callList.clear()
+ this.forEach { t, u ->
+ callList.add(u)
+ }
+ }
+ }
+ }
+
override fun onPause() {
super.onPause()
/* unregister battery changes */
@@ -383,7 +474,19 @@ internal class LauncherHome : Fragment() {
/* to-do list */
private fun showTodoList() {
- binding.notes.adapter = TodoAdapter(null, requireContext())
+ if (binding.missedCalls.isChecked == true) {
+ if (callList.size == 0) {
+ GlobalScope.launch { getCallDetails() }
+ } else {
+ BLog.LOGE("callList >>> ${callList.size}")
+ binding.notes.adapter = MissedCallsAdapter(callList, requireContext())
+ binding.notes.post {
+ binding.notes.invalidate()
+ }
+ }
+ } else {
+ binding.notes.adapter = TodoAdapter(null, requireContext())
+ }
}
/* get time format string */
@@ -422,3 +525,22 @@ internal class LauncherHome : Fragment() {
}
}
+
+
+class MissedCall {
+ constructor(count: Int, name: String?, number: String, type: Int, typeString: String, date : String) {
+ this.count = count
+ this.name = name ?: "unknown"
+ this.number = number
+ this.type = type
+ this.typeString = typeString
+ this.date = date
+ }
+
+ var count : Int = 1
+ var name : String = "how"
+ var number : String = ""
+ var type : Int = 0
+ var typeString : String = ""
+ var date : String = ""
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/rasel/lunar/launcher/todos/MissedCallsAdapter.kt b/app/src/main/kotlin/rasel/lunar/launcher/todos/MissedCallsAdapter.kt
new file mode 100644
index 00000000..236441ba
--- /dev/null
+++ b/app/src/main/kotlin/rasel/lunar/launcher/todos/MissedCallsAdapter.kt
@@ -0,0 +1,113 @@
+/*
+ * Lunar Launcher
+ * Copyright (C) 2022 Md Rasel Hossain
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package rasel.lunar.launcher.todos
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import androidx.recyclerview.widget.RecyclerView
+import com.google.android.material.bottomsheet.BottomSheetDialog
+import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
+import rasel.lunar.launcher.R
+import rasel.lunar.launcher.databinding.ListItemBinding
+import rasel.lunar.launcher.databinding.TodoDialogBinding
+import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
+import rasel.lunar.launcher.home.MissedCall
+import rasel.lunar.launcher.utils.BLog
+import java.util.*
+import kotlin.collections.ArrayList
+
+
+internal class MissedCallsAdapter(
+ private val callList: ArrayList,
+ private val context: Context) : RecyclerView.Adapter() {
+
+ private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
+
+ override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): MissedCallsHolder {
+ val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
+ return MissedCallsHolder(binding)
+ }
+
+ override fun getItemCount(): Int {
+// BLog.LOGE("callList.size >>> ${callList.size}")
+ return callList.size
+ }
+
+ @SuppressLint("SetTextI18n")
+ override fun onBindViewHolder(holder: MissedCallsHolder, position: Int) {
+ val todo = callList[position]
+ BLog.LOGE("callList >>> ${callList[position]}")
+ holder.view.itemText.text = "\u25CF ${if(todo.name.equals("unknown")) todo.number else { todo.name}} , ${todo.typeString} : ${todo.count} : ${todo.date}"
+
+ /* multiline texts are enabled for TodoManager */
+ holder.view.itemText.isSingleLine = false
+ /* launch edit or update dialog on item click */
+ holder.view.itemText.setOnClickListener { updateDialog(position) }
+ /* copy texts on long click */
+ holder.view.itemText.setOnLongClickListener {
+ copyToClipboard(context, todo.name)
+ true
+ }
+
+ }
+
+ inner class MissedCallsHolder(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root)
+
+ /* update dialog */
+ private fun updateDialog(position: Int) {
+ val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
+ val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(context))
+ bottomSheetDialog.setContentView(dialogBinding.root)
+ bottomSheetDialog.show()
+ bottomSheetDialog.dismissWithAnimation = true
+
+ val databaseHandler = DatabaseHandler(context)
+ val todo = databaseHandler.todos[position]
+
+ dialogBinding.apply {
+ deleteAllConfirmation.visibility = View.GONE
+ todoInput.setText(todo.name)
+ todoCancel.text = context.getString(R.string.delete)
+ todoCancel.setTextColor(ContextCompat.getColor(context, android.R.color.holo_red_light))
+ todoOk.text = context.getString(R.string.update)
+ }
+
+ /* delete the item */
+ dialogBinding.todoCancel.setOnClickListener {
+
+ }
+
+ /* update the item */
+ dialogBinding.todoOk.setOnClickListener {
+ val updatedTodoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
+ if (updatedTodoString.isNotEmpty()) {
+ todo.name = updatedTodoString
+ databaseHandler.updateTodo(todo)
+ bottomSheetDialog.dismiss()
+ } else {
+ dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/res/layout/launcher_home.xml b/app/src/main/res/layout/launcher_home.xml
index a61e5b2f..dda4a512 100644
--- a/app/src/main/res/layout/launcher_home.xml
+++ b/app/src/main/res/layout/launcher_home.xml
@@ -66,18 +66,54 @@
app:layout_constraintTop_toBottomOf="@+id/date"
app:layout_constraintVertical_bias="0.100" />
+
+
+
+
+
+
+ app:layout_constraintTop_toBottomOf="@+id/summaryChoose" />