...
This commit is contained in:
parent
ed24af2d41
commit
b1fdea3317
@ -1,3 +1,5 @@
|
||||
import org.jetbrains.kotlin.fir.scopes.debugCollectOverrides
|
||||
|
||||
plugins {
|
||||
id ("com.android.application")
|
||||
id ("kotlin-android")
|
||||
@ -22,17 +24,28 @@ android {
|
||||
isDebuggable = true
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-debug"
|
||||
resValue ("string", "app_name", "Lunar Launcher Debug")
|
||||
resValue ("string", "app_name", "Bums Launcher Debug")
|
||||
}
|
||||
|
||||
getByName("release") {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
resValue ("string", "app_name", "Lunar Launcher")
|
||||
resValue ("string", "app_name", "Bums Launcher")
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
|
||||
getByName("debug") {
|
||||
storeFile = file("./bs_debug.keystore")
|
||||
storePassword = "android"
|
||||
keyAlias = "androiddebugkey"
|
||||
keyPassword = "android"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
applicationVariants.all {
|
||||
if (buildType.name == "release") {
|
||||
outputs.all {
|
||||
@ -61,14 +74,17 @@ android {
|
||||
dependencies {
|
||||
val kotlinVersion: String? by extra
|
||||
|
||||
implementation ("androidx.appcompat:appcompat:1.6.1")
|
||||
implementation ("androidx.appcompat:appcompat:1.7.0")
|
||||
implementation ("androidx.biometric:biometric-ktx:1.2.0-alpha05")
|
||||
implementation ("androidx.browser:browser:1.8.0")
|
||||
implementation ("androidx.core:core-ktx:1.12.0")
|
||||
implementation ("androidx.core:core-ktx:1.13.1")
|
||||
implementation ("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
|
||||
implementation ("com.google.android.material:material:1.10.0")
|
||||
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4")
|
||||
implementation ("com.google.android.material:material:1.12.0")
|
||||
implementation (kotlin("stdlib", version = kotlinVersion))
|
||||
implementation ("com.github.cachapa:ExpandableLayout:2.9.2")
|
||||
implementation ("com.squareup.picasso:picasso:2.8")
|
||||
implementation ("com.squareup.picasso:picasso:2.71828")
|
||||
implementation ("androidx.work:work-runtime:2.9.1")
|
||||
implementation ("com.google.code.gson:gson:2.11.0")
|
||||
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.provider.ContactsContract
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.view.KeyEvent.ACTION_UP
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@ -201,25 +202,29 @@ internal class AppDrawer : Fragment() {
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER,
|
||||
)
|
||||
|
||||
val cursor = resolver.query(phoneUri, projection, null, null, null)
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
val idx =cursor.getColumnIndex(projection[0])
|
||||
val nameIndex = cursor.getColumnIndex(projection[1])
|
||||
val numberIndex = cursor.getColumnIndex(projection[2])
|
||||
var contactId = cursor.getString(idx)
|
||||
val name = cursor.getString(nameIndex)
|
||||
var number = cursor.getString(numberIndex)
|
||||
number = number.replace("-", "")
|
||||
if (name?.length ?: 0 > 0 && number?.length ?: 0 > 0) {
|
||||
contactList.add(SimpleContact(contactId,name, number))
|
||||
originContactList.add(SimpleContact(contactId,name, number))
|
||||
}
|
||||
Log.d("GetContact", "이름 : $name 번호 : $number ")
|
||||
}
|
||||
}
|
||||
// 데이터 계열은 반드시 닫아줘야 한다.
|
||||
cursor!!.close()
|
||||
try {
|
||||
val cursor = resolver.query(phoneUri, projection, null, null, null)
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
val idx =cursor.getColumnIndex(projection[0])
|
||||
val nameIndex = cursor.getColumnIndex(projection[1])
|
||||
val numberIndex = cursor.getColumnIndex(projection[2])
|
||||
var contactId = cursor.getString(idx)
|
||||
val name = cursor.getString(nameIndex)
|
||||
var number = cursor.getString(numberIndex)
|
||||
number = number.replace("-", "")
|
||||
if (name?.length ?: 0 > 0 && number?.length ?: 0 > 0) {
|
||||
contactList.add(SimpleContact(contactId,name, number))
|
||||
originContactList.add(SimpleContact(contactId,name, number))
|
||||
}
|
||||
Log.d("GetContact", "이름 : $name 번호 : $number ")
|
||||
}
|
||||
}
|
||||
// 데이터 계열은 반드시 닫아줘야 한다.
|
||||
cursor?.close()
|
||||
} catch ( e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,8 +243,8 @@ internal class AppDrawer : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.searchInput.setOnKeyListener { v, keyCode, event ->
|
||||
if (keyCode == 66 && contactList.size < 1 && packageList.size < 1) {
|
||||
binding.searchGoogle.performClick()
|
||||
if (keyCode == 66 && contactList.size < 1 && packageList.size < 1 && event.action == KeyEvent.ACTION_UP) {
|
||||
checkResult(binding.searchInput.text.toString())
|
||||
true
|
||||
}else {
|
||||
false
|
||||
@ -415,7 +420,8 @@ internal class AppDrawer : Fragment() {
|
||||
fun fetchApps() {
|
||||
packageList.clear()
|
||||
oringinPackageList.clear()
|
||||
GlobalScope.launch {
|
||||
try {
|
||||
|
||||
packageInfoList = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
packageManager?.queryIntentActivities(
|
||||
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER),
|
||||
@ -436,7 +442,8 @@ internal class AppDrawer : Fragment() {
|
||||
appsAdapter?.updateData(packageList)
|
||||
} }
|
||||
}!!
|
||||
}
|
||||
|
||||
} catch (e : Exception) {e.printStackTrace()}
|
||||
}
|
||||
|
||||
private fun getAlphabetItems() {
|
||||
|
||||
@ -95,19 +95,23 @@ internal class ContactMenu : BottomSheetDialogFragment() {
|
||||
)
|
||||
|
||||
BLog.LOGE("GetContact", "packageName ${packageName}")
|
||||
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
val nameIndex = cursor.getColumnIndex(projection[0])
|
||||
val numberIndex = cursor.getColumnIndex(projection[1])
|
||||
contactName = cursor.getString(nameIndex)
|
||||
var number = cursor.getString(numberIndex)
|
||||
contactPhoneNumber = number.replace("-", "")
|
||||
BLog.LOGE("GetContact", "이름 : $contactName 번호 : $contactPhoneNumber ")
|
||||
}
|
||||
}
|
||||
// 데이터 계열은 반드시 닫아줘야 한다.
|
||||
cursor!!.close()
|
||||
try {
|
||||
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
val nameIndex = cursor.getColumnIndex(projection[0])
|
||||
val numberIndex = cursor.getColumnIndex(projection[1])
|
||||
contactName = cursor.getString(nameIndex)
|
||||
var number = cursor.getString(numberIndex)
|
||||
contactPhoneNumber = number.replace("-", "")
|
||||
BLog.LOGE("GetContact", "이름 : $contactName 번호 : $contactPhoneNumber ")
|
||||
}
|
||||
}
|
||||
// 데이터 계열은 반드시 닫아줘야 한다.
|
||||
cursor!!.close()
|
||||
} catch ( e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
/* get application info */
|
||||
|
||||
|
||||
@ -25,23 +25,20 @@ import android.content.IntentFilter
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.provider.AlarmClock
|
||||
import android.provider.CallLog
|
||||
import android.text.format.DateFormat
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RadioButton
|
||||
import android.widget.Toast
|
||||
import androidx.biometric.BiometricPrompt
|
||||
import androidx.core.view.get
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import com.google.gson.Gson
|
||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
import rasel.lunar.launcher.R
|
||||
import rasel.lunar.launcher.databinding.LauncherHomeBinding
|
||||
@ -52,7 +49,6 @@ import rasel.lunar.launcher.helpers.Constants.Companion.KEY_LOCK_METHOD
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_TIME_FORMAT
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_TODO_LOCK
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||
import rasel.lunar.launcher.helpers.SwipeTouchListener
|
||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.biometricPromptInfo
|
||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.canAuthenticate
|
||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
|
||||
@ -61,12 +57,11 @@ import rasel.lunar.launcher.home.weather.WeatherExecutor
|
||||
import rasel.lunar.launcher.qaccess.QuickAccess
|
||||
import rasel.lunar.launcher.settings.SettingsActivity
|
||||
import rasel.lunar.launcher.todos.MissedCallsAdapter
|
||||
import rasel.lunar.launcher.todos.TodoAdapter
|
||||
import rasel.lunar.launcher.todos.TodoManager
|
||||
import rasel.lunar.launcher.utils.BLog
|
||||
import rasel.lunar.launcher.utils.MissedCallGetter
|
||||
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
internal class LauncherHome : Fragment() {
|
||||
@ -85,12 +80,18 @@ internal class LauncherHome : Fragment() {
|
||||
batteryReceiver = BatteryReceiver(binding.batteryProgress)
|
||||
|
||||
binding.favAppsGroup.visibility = View.GONE
|
||||
Thread("CALLED").run {
|
||||
getCallDetails()
|
||||
}
|
||||
|
||||
mWorkManager = WorkManager.getInstance(lActivity!!.application);
|
||||
mWorkManager?.enqueue(OneTimeWorkRequestBuilder<MissedCallGetter>().addTag("MissedCallGetter").build())
|
||||
BLog.LOGE("onCreateView()")
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private var mSavedWorkInfo: LiveData<List<WorkInfo>>? = null
|
||||
fun getOutputWorkInfo(): LiveData<List<WorkInfo>> {
|
||||
return mSavedWorkInfo!!
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
/* handle gesture events */
|
||||
@ -98,11 +99,14 @@ internal class LauncherHome : Fragment() {
|
||||
batteryProgressGestures()
|
||||
todosGestures()
|
||||
|
||||
BLog.LOGE("onViewCreated()")
|
||||
|
||||
// mWorkManager.
|
||||
/* refresh the to-do list after getting back from TodoManager */
|
||||
fragManager.addOnBackStackChangedListener {
|
||||
BLog.LOGE("addOnBackStackChangedListener()")
|
||||
shouldResume = if (fragManager.backStackEntryCount == 0) {
|
||||
binding.root.visibility = View.VISIBLE
|
||||
showTodoList()
|
||||
true
|
||||
} else {
|
||||
binding.root.visibility = View.GONE
|
||||
@ -113,6 +117,7 @@ internal class LauncherHome : Fragment() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
BLog.LOGE("onResume()")
|
||||
if (shouldResume) {
|
||||
/* register battery changes */
|
||||
requireContext().registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
@ -130,83 +135,31 @@ internal class LauncherHome : Fragment() {
|
||||
|
||||
/* show weather */
|
||||
WeatherExecutor(settingsPrefs).generateWeatherString(binding.weather)
|
||||
/* show to-do list */
|
||||
showTodoList()
|
||||
mSavedWorkInfo = mWorkManager?.getWorkInfosByTagLiveData("MissedCallGetter");
|
||||
getOutputWorkInfo().observeForever {
|
||||
it.last()?.outputData?.keyValueMap?.forEach { t, u ->
|
||||
try {
|
||||
if (u is String) {
|
||||
Gson().fromJson(u,MissedCall::class.java)?.let {
|
||||
callList.add(it)
|
||||
}
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
|
||||
} finally {
|
||||
showTodoList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var mWorkManager: WorkManager? = null
|
||||
|
||||
var callList = arrayListOf<MissedCall>()
|
||||
|
||||
|
||||
private fun getCallDetails() {
|
||||
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<String>(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)
|
||||
var missedCalls = hashMapOf<String, MissedCall>()
|
||||
if (missedCalls.size != callList.size) {
|
||||
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"
|
||||
}
|
||||
}
|
||||
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()
|
||||
if (callList.size == missedCalls.size) {
|
||||
} else {
|
||||
callList.clear()
|
||||
missedCalls.forEach { t, u ->
|
||||
callList.add(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
@ -463,22 +416,23 @@ internal class LauncherHome : Fragment() {
|
||||
|
||||
/* launch TodoManager fragment */
|
||||
private fun launchTodoManager() {
|
||||
fragManager.beginTransaction().replace(R.id.mainFragmentsContainer, TodoManager())
|
||||
.addToBackStack("").commit()
|
||||
// fragManager.beginTransaction().replace(R.id.mainFragmentsContainer, TodoManager())
|
||||
// .addToBackStack("").commit()
|
||||
}
|
||||
|
||||
/* to-do list */
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun showTodoList() {
|
||||
if (binding.missedCalls.isChecked == true) {
|
||||
if (callList.size > 0) {
|
||||
BLog.LOGE("callList >>> ${callList.size}")
|
||||
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())?.apply {
|
||||
this.notifyDataSetChanged()
|
||||
if (binding.missedCalls.isChecked) {
|
||||
if (callList.size > 0 && isAdded && isResumed && isVisible) {
|
||||
try {
|
||||
BLog.LOGE("callList >>> ${callList.size}")
|
||||
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())
|
||||
} catch (e : Exception) {
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
binding.notes.adapter = TodoAdapter(null, requireContext())
|
||||
// binding.notes.adapter = TodoAdapter(null, requireContext())
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,4 +490,9 @@ class MissedCall {
|
||||
var type : Int = 0
|
||||
var typeString : String = ""
|
||||
var date : String = ""
|
||||
|
||||
fun toJson() : String {
|
||||
return Gson().toJson(this)
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,107 +1,107 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package rasel.lunar.launcher.todos
|
||||
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.content.ContentValues
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.database.DatabaseUtils
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_CREATED
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_ID
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_NAME
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_NAME
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_VERSION
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_TABLE_NAME
|
||||
import java.util.ArrayList
|
||||
|
||||
|
||||
internal class DatabaseHandler(context: Context?) :
|
||||
SQLiteOpenHelper(context, TODO_DATABASE_NAME, null, TODO_DATABASE_VERSION) {
|
||||
|
||||
/* create database */
|
||||
override fun onCreate(database: SQLiteDatabase) {
|
||||
val createTodoTable = "CREATE TABLE " + TODO_TABLE_NAME + " (" +
|
||||
TODO_COLUMN_ID + " integer PRIMARY KEY AUTOINCREMENT," +
|
||||
TODO_COLUMN_CREATED + " datetime DEFAULT CURRENT_TIMESTAMP," +
|
||||
TODO_COLUMN_NAME + " varchar)"
|
||||
database.execSQL(createTodoTable)
|
||||
}
|
||||
|
||||
override fun onUpgrade(sqLiteDatabase: SQLiteDatabase, i: Int, i1: Int) {}
|
||||
|
||||
/* add new to-do entry */
|
||||
fun addTodo(todo: Todo) {
|
||||
val database = writableDatabase
|
||||
val contentValues = ContentValues()
|
||||
contentValues.put(TODO_COLUMN_NAME, todo.name)
|
||||
database.insert(TODO_TABLE_NAME, null, contentValues)
|
||||
}
|
||||
|
||||
/* update or edit existing to-do */
|
||||
fun updateTodo(todo: Todo) {
|
||||
val database = writableDatabase
|
||||
val contentValues = ContentValues()
|
||||
contentValues.put(TODO_COLUMN_NAME, todo.name)
|
||||
database.update(
|
||||
TODO_TABLE_NAME,
|
||||
contentValues,
|
||||
"$TODO_COLUMN_ID=?",
|
||||
arrayOf(todo.id.toString())
|
||||
)
|
||||
}
|
||||
|
||||
/* delete a single to-do */
|
||||
fun deleteTodo(todoId: Long) {
|
||||
writableDatabase.delete(TODO_TABLE_NAME,
|
||||
"$TODO_COLUMN_ID=?", arrayOf(todoId.toString()))
|
||||
}
|
||||
|
||||
/* delete all existing todos at once */
|
||||
fun deleteAll() {
|
||||
writableDatabase.delete(TODO_TABLE_NAME, null, null)
|
||||
}
|
||||
|
||||
@get:SuppressLint("Range")
|
||||
val todos: ArrayList<Todo>
|
||||
get() {
|
||||
val todoList = ArrayList<Todo>()
|
||||
val queryResult =
|
||||
readableDatabase.rawQuery("SELECT * from $TODO_TABLE_NAME", null)
|
||||
|
||||
if (queryResult.moveToFirst()) {
|
||||
do {
|
||||
val todo = Todo()
|
||||
todo.id = queryResult.getLong(queryResult.getColumnIndex(TODO_COLUMN_ID))
|
||||
todo.name = queryResult.getString(queryResult.getColumnIndex(TODO_COLUMN_NAME))
|
||||
todoList.add(todo)
|
||||
} while (queryResult.moveToNext())
|
||||
}
|
||||
|
||||
queryResult.close()
|
||||
return todoList
|
||||
}
|
||||
|
||||
/* check if any item exists in the database */
|
||||
val isTodoExists: Boolean get() {
|
||||
return DatabaseUtils.queryNumEntries(readableDatabase, TODO_TABLE_NAME, 1.toString()) > 0
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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 <http://www.gnu.org/licenses/>.
|
||||
// */
|
||||
//
|
||||
//package rasel.lunar.launcher.todos
|
||||
//
|
||||
//import android.database.sqlite.SQLiteOpenHelper
|
||||
//import android.database.sqlite.SQLiteDatabase
|
||||
//import android.content.ContentValues
|
||||
//import android.annotation.SuppressLint
|
||||
//import android.content.Context
|
||||
//import android.database.DatabaseUtils
|
||||
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_CREATED
|
||||
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_ID
|
||||
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_NAME
|
||||
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_NAME
|
||||
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_VERSION
|
||||
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_TABLE_NAME
|
||||
//import java.util.ArrayList
|
||||
//
|
||||
//
|
||||
//internal class DatabaseHandler(context: Context?) :
|
||||
// SQLiteOpenHelper(context, TODO_DATABASE_NAME, null, TODO_DATABASE_VERSION) {
|
||||
//
|
||||
// /* create database */
|
||||
// override fun onCreate(database: SQLiteDatabase) {
|
||||
// val createTodoTable = "CREATE TABLE " + TODO_TABLE_NAME + " (" +
|
||||
// TODO_COLUMN_ID + " integer PRIMARY KEY AUTOINCREMENT," +
|
||||
// TODO_COLUMN_CREATED + " datetime DEFAULT CURRENT_TIMESTAMP," +
|
||||
// TODO_COLUMN_NAME + " varchar)"
|
||||
// database.execSQL(createTodoTable)
|
||||
// }
|
||||
//
|
||||
// override fun onUpgrade(sqLiteDatabase: SQLiteDatabase, i: Int, i1: Int) {}
|
||||
//
|
||||
// /* add new to-do entry */
|
||||
// fun addTodo(todo: Todo) {
|
||||
// val database = writableDatabase
|
||||
// val contentValues = ContentValues()
|
||||
// contentValues.put(TODO_COLUMN_NAME, todo.name)
|
||||
// database.insert(TODO_TABLE_NAME, null, contentValues)
|
||||
// }
|
||||
//
|
||||
// /* update or edit existing to-do */
|
||||
// fun updateTodo(todo: Todo) {
|
||||
// val database = writableDatabase
|
||||
// val contentValues = ContentValues()
|
||||
// contentValues.put(TODO_COLUMN_NAME, todo.name)
|
||||
// database.update(
|
||||
// TODO_TABLE_NAME,
|
||||
// contentValues,
|
||||
// "$TODO_COLUMN_ID=?",
|
||||
// arrayOf(todo.id.toString())
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// /* delete a single to-do */
|
||||
// fun deleteTodo(todoId: Long) {
|
||||
// writableDatabase.delete(TODO_TABLE_NAME,
|
||||
// "$TODO_COLUMN_ID=?", arrayOf(todoId.toString()))
|
||||
// }
|
||||
//
|
||||
// /* delete all existing todos at once */
|
||||
// fun deleteAll() {
|
||||
// writableDatabase.delete(TODO_TABLE_NAME, null, null)
|
||||
// }
|
||||
//
|
||||
// @get:SuppressLint("Range")
|
||||
// val todos: ArrayList<Todo>
|
||||
// get() {
|
||||
// val todoList = ArrayList<Todo>()
|
||||
//// val queryResult =
|
||||
//// readableDatabase.rawQuery("SELECT * from $TODO_TABLE_NAME", null)
|
||||
////
|
||||
//// if (queryResult.moveToFirst()) {
|
||||
//// do {
|
||||
//// val todo = Todo()
|
||||
//// todo.id = queryResult.getLong(queryResult.getColumnIndex(TODO_COLUMN_ID))
|
||||
//// todo.name = queryResult.getString(queryResult.getColumnIndex(TODO_COLUMN_NAME))
|
||||
//// todoList.add(todo)
|
||||
//// } while (queryResult.moveToNext())
|
||||
//// }
|
||||
////
|
||||
//// queryResult.close()
|
||||
// return todoList
|
||||
// }
|
||||
//
|
||||
// /* check if any item exists in the database */
|
||||
// val isTodoExists: Boolean get() {
|
||||
// return DatabaseUtils.queryNumEntries(readableDatabase, TODO_TABLE_NAME, 1.toString()) > 0
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
@ -75,39 +75,39 @@ internal class MissedCallsAdapter(
|
||||
|
||||
/* 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)
|
||||
}
|
||||
}
|
||||
// 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)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package rasel.lunar.launcher.todos
|
||||
|
||||
|
||||
internal class Todo {
|
||||
var id: Long = -1
|
||||
var name = ""
|
||||
}
|
||||
///*
|
||||
// * 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 <http://www.gnu.org/licenses/>.
|
||||
// */
|
||||
//
|
||||
//package rasel.lunar.launcher.todos
|
||||
//
|
||||
//
|
||||
//internal class Todo {
|
||||
// var id: Long = -1
|
||||
// var name = ""
|
||||
//}
|
||||
|
||||
@ -1,127 +1,129 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.Constants.Companion.KEY_TODO_COUNTS
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
|
||||
import java.util.*
|
||||
|
||||
|
||||
internal class TodoAdapter(
|
||||
private val todoManager: TodoManager?,
|
||||
private val context: Context) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {
|
||||
|
||||
private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
|
||||
private val todoList = DatabaseHandler(context).todos
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): TodoViewHolder {
|
||||
val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
|
||||
return TodoViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
/* if current fragment is LauncherHome,
|
||||
then return size following the settings value */
|
||||
val sharedPreferences = context.getSharedPreferences(PREFS_SETTINGS, 0)
|
||||
val numberOfTodos = sharedPreferences.getInt(KEY_TODO_COUNTS, 3)
|
||||
return if (currentFragment !is TodoManager) {
|
||||
todoList.size.coerceAtMost(numberOfTodos)
|
||||
} else {
|
||||
todoList.size
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
|
||||
val todo = todoList[position]
|
||||
|
||||
holder.view.itemText.text = "\u25CF ${todo.name}"
|
||||
|
||||
if (currentFragment is TodoManager) {
|
||||
/* 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
|
||||
}
|
||||
} else {
|
||||
/* single line text for home screen */
|
||||
holder.view.itemText.isSingleLine = true
|
||||
}
|
||||
}
|
||||
|
||||
inner class TodoViewHolder(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 {
|
||||
databaseHandler.deleteTodo(todo.id)
|
||||
bottomSheetDialog.dismiss()
|
||||
todoManager?.refreshList()
|
||||
}
|
||||
|
||||
/* 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()
|
||||
todoManager?.refreshList()
|
||||
} else {
|
||||
dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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 <http://www.gnu.org/licenses/>.
|
||||
// */
|
||||
//
|
||||
//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.Constants.Companion.KEY_TODO_COUNTS
|
||||
//import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||
//import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
|
||||
//import java.util.*
|
||||
//
|
||||
//
|
||||
//internal class TodoAdapter(
|
||||
// private val todoManager: TodoManager?,
|
||||
// private val context: Context) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {
|
||||
//
|
||||
// private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
|
||||
//// private val todoList = DatabaseHandler(context).todos
|
||||
//
|
||||
// override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): TodoViewHolder {
|
||||
// val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
|
||||
// return TodoViewHolder(binding)
|
||||
// }
|
||||
//
|
||||
// override fun getItemCount(): Int {
|
||||
// /* if current fragment is LauncherHome,
|
||||
// then return size following the settings value */
|
||||
// val sharedPreferences = context.getSharedPreferences(PREFS_SETTINGS, 0)
|
||||
// val numberOfTodos = sharedPreferences.getInt(KEY_TODO_COUNTS, 3)
|
||||
// return if (currentFragment !is TodoManager) {
|
||||
//// todoList.size.coerceAtMost(numberOfTodos)
|
||||
// 0
|
||||
// } else {
|
||||
//// todoList.size
|
||||
// 0
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @SuppressLint("SetTextI18n")
|
||||
// override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
|
||||
//// val todo = todoList[position]
|
||||
//
|
||||
//// holder.view.itemText.text = "\u25CF ${todo.name}"
|
||||
////
|
||||
//// if (currentFragment is TodoManager) {
|
||||
//// /* 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
|
||||
//// }
|
||||
//// } else {
|
||||
//// /* single line text for home screen */
|
||||
//// holder.view.itemText.isSingleLine = true
|
||||
//// }
|
||||
// }
|
||||
//
|
||||
// inner class TodoViewHolder(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 {
|
||||
// databaseHandler.deleteTodo(todo.id)
|
||||
// bottomSheetDialog.dismiss()
|
||||
// todoManager?.refreshList()
|
||||
// }
|
||||
//
|
||||
// /* 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()
|
||||
// todoManager?.refreshList()
|
||||
// } else {
|
||||
// dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
@ -1,129 +1,129 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package rasel.lunar.launcher.todos
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
import rasel.lunar.launcher.R
|
||||
import rasel.lunar.launcher.databinding.TodoDialogBinding
|
||||
import rasel.lunar.launcher.databinding.TodoManagerBinding
|
||||
import java.util.*
|
||||
|
||||
|
||||
internal class TodoManager : Fragment() {
|
||||
|
||||
private lateinit var binding: TodoManagerBinding
|
||||
private lateinit var databaseHandler: DatabaseHandler
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
|
||||
binding = TodoManagerBinding.inflate(inflater, container, false)
|
||||
databaseHandler = DatabaseHandler(requireContext())
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
/* click listeners for add new and delete all buttons */
|
||||
binding.addNew.setOnClickListener { addNewDialog() }
|
||||
binding.deleteAll.setOnClickListener { deleteAllDialog() }
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
refreshList()
|
||||
lActivity!!.viewPager.isUserInputEnabled = false
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
lActivity!!.viewPager.isUserInputEnabled = true
|
||||
}
|
||||
|
||||
fun refreshList() {
|
||||
binding.todos.adapter = TodoAdapter(this, requireContext())
|
||||
}
|
||||
|
||||
/* add new dialog */
|
||||
private fun addNewDialog() {
|
||||
val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
|
||||
val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
bottomSheetDialog.setContentView(dialogBinding.root)
|
||||
bottomSheetDialog.show()
|
||||
bottomSheetDialog.dismissWithAnimation = true
|
||||
|
||||
dialogBinding.deleteAllConfirmation.visibility = View.GONE
|
||||
/* automatic keyboard popup */
|
||||
dialogBinding.todoInput.requestFocus()
|
||||
val inputMethodManager = lActivity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.showSoftInput(dialogBinding.todoInput, InputMethodManager.SHOW_IMPLICIT)
|
||||
|
||||
/* dismiss the dialog on cancel button click */
|
||||
dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
|
||||
/* add new item to the database */
|
||||
dialogBinding.todoOk.setOnClickListener {
|
||||
val todo = Todo()
|
||||
val todoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
|
||||
if (todoString.isNotEmpty()) {
|
||||
todo.name = todoString
|
||||
databaseHandler.addTodo(todo)
|
||||
bottomSheetDialog.dismiss()
|
||||
refreshList()
|
||||
} else {
|
||||
dialogBinding.todoInput.error = getString(R.string.empty_text_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* delete all dialog */
|
||||
private fun deleteAllDialog() {
|
||||
val bottomSheetDialog = BottomSheetDialog(lActivity!!)
|
||||
val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
bottomSheetDialog.setContentView(dialogBinding.root)
|
||||
bottomSheetDialog.show()
|
||||
bottomSheetDialog.dismissWithAnimation = true
|
||||
|
||||
/* if any item does not exist, then disable the ok button */
|
||||
if (!databaseHandler.isTodoExists) {
|
||||
dialogBinding.todoOk.isEnabled = false
|
||||
}
|
||||
|
||||
dialogBinding.todoInput.visibility = View.GONE
|
||||
dialogBinding.todoOk.setTextColor(ContextCompat.getColor(requireContext(), android.R.color.holo_red_light))
|
||||
|
||||
/* dismiss the dialog on cancel button click */
|
||||
dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
|
||||
/* delete all the existing items from the database */
|
||||
dialogBinding.todoOk.setOnClickListener {
|
||||
databaseHandler.deleteAll()
|
||||
bottomSheetDialog.dismiss()
|
||||
refreshList()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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 <http://www.gnu.org/licenses/>.
|
||||
// */
|
||||
//
|
||||
//package rasel.lunar.launcher.todos
|
||||
//
|
||||
//import android.content.Context
|
||||
//import android.os.Bundle
|
||||
//import android.view.LayoutInflater
|
||||
//import android.view.View
|
||||
//import android.view.ViewGroup
|
||||
//import android.view.inputmethod.InputMethodManager
|
||||
//import androidx.core.content.ContextCompat
|
||||
//import androidx.fragment.app.Fragment
|
||||
//import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
//import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
//import rasel.lunar.launcher.R
|
||||
//import rasel.lunar.launcher.databinding.TodoDialogBinding
|
||||
//import rasel.lunar.launcher.databinding.TodoManagerBinding
|
||||
//import java.util.*
|
||||
//
|
||||
//
|
||||
//internal class TodoManager : Fragment() {
|
||||
//
|
||||
// private lateinit var binding: TodoManagerBinding
|
||||
// private lateinit var databaseHandler: DatabaseHandler
|
||||
//
|
||||
// override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
//
|
||||
// binding = TodoManagerBinding.inflate(inflater, container, false)
|
||||
// databaseHandler = DatabaseHandler(requireContext())
|
||||
//
|
||||
// return binding.root
|
||||
// }
|
||||
//
|
||||
// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
// super.onViewCreated(view, savedInstanceState)
|
||||
// /* click listeners for add new and delete all buttons */
|
||||
// binding.addNew.setOnClickListener { addNewDialog() }
|
||||
// binding.deleteAll.setOnClickListener { deleteAllDialog() }
|
||||
// }
|
||||
//
|
||||
// override fun onResume() {
|
||||
// super.onResume()
|
||||
// refreshList()
|
||||
// lActivity!!.viewPager.isUserInputEnabled = false
|
||||
// }
|
||||
//
|
||||
// override fun onPause() {
|
||||
// super.onPause()
|
||||
// lActivity!!.viewPager.isUserInputEnabled = true
|
||||
// }
|
||||
//
|
||||
// fun refreshList() {
|
||||
// binding.todos.adapter = TodoAdapter(this, requireContext())
|
||||
// }
|
||||
//
|
||||
// /* add new dialog */
|
||||
// private fun addNewDialog() {
|
||||
// val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
|
||||
// val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
// bottomSheetDialog.setContentView(dialogBinding.root)
|
||||
// bottomSheetDialog.show()
|
||||
// bottomSheetDialog.dismissWithAnimation = true
|
||||
//
|
||||
// dialogBinding.deleteAllConfirmation.visibility = View.GONE
|
||||
// /* automatic keyboard popup */
|
||||
// dialogBinding.todoInput.requestFocus()
|
||||
// val inputMethodManager = lActivity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
// inputMethodManager.showSoftInput(dialogBinding.todoInput, InputMethodManager.SHOW_IMPLICIT)
|
||||
//
|
||||
// /* dismiss the dialog on cancel button click */
|
||||
// dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
|
||||
// /* add new item to the database */
|
||||
// dialogBinding.todoOk.setOnClickListener {
|
||||
// val todo = Todo()
|
||||
// val todoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
|
||||
// if (todoString.isNotEmpty()) {
|
||||
// todo.name = todoString
|
||||
// databaseHandler.addTodo(todo)
|
||||
// bottomSheetDialog.dismiss()
|
||||
// refreshList()
|
||||
// } else {
|
||||
// dialogBinding.todoInput.error = getString(R.string.empty_text_field)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /* delete all dialog */
|
||||
// private fun deleteAllDialog() {
|
||||
// val bottomSheetDialog = BottomSheetDialog(lActivity!!)
|
||||
// val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
// bottomSheetDialog.setContentView(dialogBinding.root)
|
||||
// bottomSheetDialog.show()
|
||||
// bottomSheetDialog.dismissWithAnimation = true
|
||||
//
|
||||
// /* if any item does not exist, then disable the ok button */
|
||||
// if (!databaseHandler.isTodoExists) {
|
||||
// dialogBinding.todoOk.isEnabled = false
|
||||
// }
|
||||
//
|
||||
// dialogBinding.todoInput.visibility = View.GONE
|
||||
// dialogBinding.todoOk.setTextColor(ContextCompat.getColor(requireContext(), android.R.color.holo_red_light))
|
||||
//
|
||||
// /* dismiss the dialog on cancel button click */
|
||||
// dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
|
||||
// /* delete all the existing items from the database */
|
||||
// dialogBinding.todoOk.setOnClickListener {
|
||||
// databaseHandler.deleteAll()
|
||||
// bottomSheetDialog.dismiss()
|
||||
// refreshList()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
113
app/src/main/kotlin/rasel/lunar/launcher/utils/DataManager.kt
Normal file
113
app/src/main/kotlin/rasel/lunar/launcher/utils/DataManager.kt
Normal file
@ -0,0 +1,113 @@
|
||||
package rasel.lunar.launcher.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.IntentService
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.os.IBinder
|
||||
import android.provider.CallLog
|
||||
import androidx.work.Data
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
import rasel.lunar.launcher.home.MissedCall
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
class MissedCallGetter : Worker {
|
||||
|
||||
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun doWork(): Result {
|
||||
var resultData = Data.Builder()
|
||||
var dateParam = Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)).time.toString()
|
||||
lActivity?.contentResolver?.query(
|
||||
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<String>(dateParam, "2"), CallLog.Calls.DATE + " desc")?.let { managedCursor ->
|
||||
try {
|
||||
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)
|
||||
var missedCalls = hashMapOf<String, MissedCall>()
|
||||
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"
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
missedCalls.forEach { t, u ->
|
||||
resultData.put(t, u.toJson())
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
} finally {
|
||||
managedCursor.close()
|
||||
}
|
||||
}
|
||||
return Result.success(resultData.build());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user