Compare commits

...

4 Commits

Author SHA1 Message Date
lunaticbum
e75aa2eaa9 .. 2024-10-08 16:00:14 +09:00
lunaticbum
f914c7694f .. 2024-10-08 16:00:08 +09:00
lunaticbum
dd92a39f16 Merge branch 'main' of https://dev.lunaticbum.kr/lun_admin/lun_launcher 2024-10-08 15:59:51 +09:00
lunaticbum
58b981f426 ... 2024-10-08 15:59:47 +09:00
11 changed files with 244 additions and 476 deletions

View File

@ -377,7 +377,7 @@ internal class AppDrawer : Fragment() {
}
}
}
appQuery = newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).limit(20).find()
appQuery = newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).limit(18).find()
appQuery?.let {
if(it.size > 0) {
WorkersDb.getRealm().apply {
@ -416,7 +416,7 @@ internal class AppDrawer : Fragment() {
}
}
contactQuery = newQ.sort(Pair("touchCount", Sort.DESCENDING),Pair("lastedTouchDateTime",Sort.DESCENDING)).find()
contactQuery = newQ.sort(Pair("touchCount", Sort.DESCENDING),Pair("lastedTouchDateTime",Sort.DESCENDING)).limit(18).find()
contactQuery?.let {
if (it.size > 0)
WorkersDb.getRealm().apply {

View File

@ -50,6 +50,7 @@ import com.google.android.material.button.MaterialButton
import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.Gson
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R
import rasel.lunar.launcher.apps.AppDrawer.Companion.appNamesPrefs
@ -62,7 +63,9 @@ import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FAVORITE_APPS
import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenHeight
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenWidth
import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.WorkersDb
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
@ -96,7 +99,36 @@ internal class AppMenu : BottomSheetDialogFragment() {
/* get default app name */
defAppName = packageManager.resolveActivity(Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(packageName), 0)?.loadLabel(packageManager).toString()
WorkersDb.getRealm().apply {
writeBlocking {
var result = query<AppInfo>("pkgName == $0",packageName).find()
if(result.size > 0) {
val app = result.first()
binding.totalTouch.text = "총 실행 횟수 : ".plus(app.clickCount.toString())
binding.lastTouchDate.text = "최종 실행 일시 : ".plus(SimpleDateFormat("yyyy-MM-dd HH:mm").format(Date(app.lastUseDate)))
// app.clickCount = app.clickCount + 15
// app.lastUseDate = Math.max(app.lastUseDate, System.currentTimeMillis())
// app.clickCount = app.clickCount + 15
// app.lastUseDate = Math.max(app.lastUseDate, System.currentTimeMillis())
}
}
}
fun update() {
WorkersDb.getRealm().apply {
writeBlocking {
var result = query<AppInfo>("pkgName == $0",packageName).find()
if(result.size > 0) {
val app = result.first()
app.clickCount = app.clickCount + 15
}
}
}
}
binding.totalTouch.setOnClickListener { update() }
binding.lastTouchDate.setOnClickListener { update() }
/* set application name and package name */
binding.appName.apply {
setText(appNamesPrefs?.getString(packageName, defAppName))
@ -104,9 +136,6 @@ internal class AppMenu : BottomSheetDialogFragment() {
}
binding.appPackage.text = packageName
/* favorite apps */
favoriteApps()
return binding.root
}
@ -129,56 +158,7 @@ internal class AppMenu : BottomSheetDialogFragment() {
binding.appUninstall.setOnClickListener { uninstall() }
}
/* manage initial preview and clicks for favorite apps */
@SuppressLint("PrivateResource")
private fun favoriteApps() {
val sharedPreferences = requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
val enabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.material_on_surface_stroke))
val disabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.m3_chip_stroke_color))
for (position in 1..MAX_FAVORITE_APPS) {
val button = outlinedButton
val savedPackageName = sharedPreferences.getString(KEY_APP_NO_ + position, "")
/* set previews */
if (packageName == savedPackageName) button.isChecked = true
if (savedPackageName?.isNotEmpty() == true) button.strokeColor = enabledStroke
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
packageManager.getPackageInfo(savedPackageName!!, PackageManager.PackageInfoFlags.of(0))
else
packageManager.getPackageInfo(savedPackageName!!, 0)
} catch (e: PackageManager.NameNotFoundException) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
e.printStackTrace()
}
/* listen on clicks */
binding.favGroup.addOnButtonCheckedListener { _: MaterialButtonToggleGroup?,
checkedId: Int, isChecked: Boolean ->
try {
if (checkedId == button.id) {
if (isChecked) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().putString(KEY_APP_NO_ + position, packageName).apply()
button.strokeColor = enabledStroke
} else {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
private fun appName() {
binding.appName.setOnFocusChangeListener { _, hasFocus ->
@ -382,18 +362,6 @@ internal class AppMenu : BottomSheetDialogFragment() {
this.dismiss()
}
/* create and add an outlined button to the toggle group */
private val outlinedButton: MaterialButton get() {
val style = com.google.android.material.R.attr.materialButtonOutlinedStyle
val button = MaterialButton(requireContext(), null, style)
button.layoutParams = LinearLayoutCompat.LayoutParams(
LinearLayoutCompat.LayoutParams.WRAP_CONTENT,
LinearLayoutCompat.LayoutParams.WRAP_CONTENT, 1F
)
binding.favGroup.addView(button)
return button
}
/* long value to local date-time format */
private fun dateTimeFormat(long: Long) : String = SimpleDateFormat.getDateTimeInstance().format(Date(long))

View File

@ -93,6 +93,16 @@ internal class AppsAdapter(
/* on long click - open app menu */
setOnLongClickListener {
WorkersDb.getRealm().apply {
writeBlocking {
var result = query<AppInfo>("pkgName == $0",item.pkgName).find()
if(result.size > 0) {
val app = result.first()
app.clickCount = app.clickCount + 15
app.lastUseDate = Math.max(app.lastUseDate, System.currentTimeMillis())
}
}
}
AppMenu().apply {
}.show(fragmentManager, item.pkgName)
true

View File

@ -26,12 +26,14 @@ import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import io.realm.kotlin.ext.query
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import rasel.lunar.launcher.databinding.ContactItemBinding
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.workers.RecentCallGetter
import rasel.lunar.launcher.workers.WorkersDb
import java.util.Date
@ -62,11 +64,22 @@ internal class ContactAdapter (
holder.view.root.apply {
/* on click - open app */
setOnClickListener {
ContactMenu().show(fragmentManager, item.id.toString())
}
/* on long click - open app menu */
setOnLongClickListener {
WorkersDb.getRealm().writeBlocking {
if (item.id!=null && item.id?.length ?: 0 > 0) {
val result = query<SimpleContact>().query("id == $0", item.id).find()
if(result.size > 0){
var contact = result.first()
contact.touchCount = contact.touchCount + 1
contact.lastedTouchDateTime = System.currentTimeMillis()
}
}
}
// BLog.LOGE("item.id.toString() >> ${item.id.toString()}")
ContactMenu().show(fragmentManager, item.id.toString())
true

View File

@ -18,65 +18,63 @@
package rasel.lunar.launcher.apps
import android.annotation.SuppressLint
import android.app.ActivityOptions
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.res.ColorStateList
import android.graphics.Rect
import android.icu.text.SimpleDateFormat
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.ContactsContract
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.content.FileProvider
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.button.MaterialButton
import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.ActivityBrowserDialogBinding
import rasel.lunar.launcher.databinding.ContactMenuBinding
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APP_NO_
import rasel.lunar.launcher.helpers.Constants.Companion.MAX_FAVORITE_APPS
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FAVORITE_APPS
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenHeight
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenWidth
import rasel.lunar.launcher.utils.BLog
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import rasel.lunar.launcher.workers.WorkersDb
import java.text.SimpleDateFormat
import java.util.Date
internal class ContactMenu : BottomSheetDialogFragment() {
private lateinit var binding: ContactMenuBinding
private lateinit var packageName: String
private lateinit var packageManager: PackageManager
private lateinit var appInfo: ApplicationInfo
private lateinit var defAppName: String
private lateinit var contactId: String
var contactName : String = ""
var contactPhoneNumber : String = ""
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = ContactMenuBinding.inflate(inflater, container, false)
/* get package name from fragment's tag */
packageName = tag.toString()
contactId = tag.toString()
WorkersDb.getRealm().writeBlocking {
if (contactId != null && contactId.length ?: 0 > 0) {
val result = query<SimpleContact>().query("id == $0", contactId).find()
if(result.size > 0){
var contact = result.first()
binding.totalTouch.text = "총 연락 횟수 : ".plus(contact.touchCount.toString())
binding.lastTouchDate.text = "마지막 연락 시간 : ".plus(SimpleDateFormat("yyyy-MM-dd HH:mm").format(Date(contact.lastedTouchDateTime)))
}
}
}
fun update() {
WorkersDb.getRealm().writeBlocking {
if (contactId != null && contactId.length ?: 0 > 0) {
val result = query<SimpleContact>().query("id == $0", contactId).find()
if(result.size > 0){
var contact = result.first()
contact.touchCount = contact.touchCount + 15
}
}
}
}
binding.totalTouch.setOnClickListener { update() }
binding.lastTouchDate.setOnClickListener { update() }
val resolver = lActivity!!.contentResolver
val phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
val projection = arrayOf(
@ -84,9 +82,9 @@ internal class ContactMenu : BottomSheetDialogFragment() {
ContactsContract.CommonDataKinds.Phone.NUMBER,
)
BLog.LOGE("GetContact", "packageName ${packageName}")
BLog.LOGE("GetContact", "packageName ${contactId}")
try {
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null , null)
if (cursor != null) {
while (cursor.moveToNext()) {
val nameIndex = cursor.getColumnIndex(projection[0])
@ -120,6 +118,8 @@ internal class ContactMenu : BottomSheetDialogFragment() {
//
appName()
binding.detailedInfo.setOnClickListener { detailedInfo() }
binding.call.setOnClickListener { callPhone() }
binding.sms.setOnClickListener { sendSms() }
// binding.activityBrowser.setOnClickListener { activityBrowser() }
// binding.appStore.setOnClickListener { appStore() }
// binding.appFreeform.setOnClickListener { freeform() }
@ -128,56 +128,7 @@ internal class ContactMenu : BottomSheetDialogFragment() {
// binding.appUninstall.setOnClickListener { uninstall() }
}
/* manage initial preview and clicks for favorite apps */
@SuppressLint("PrivateResource")
private fun favoriteApps() {
val sharedPreferences = requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
val enabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.material_on_surface_stroke))
val disabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.m3_chip_stroke_color))
for (position in 1..MAX_FAVORITE_APPS) {
val button = outlinedButton
val savedPackageName = sharedPreferences.getString(KEY_APP_NO_ + position, "")
/* set previews */
if (packageName == savedPackageName) button.isChecked = true
if (savedPackageName?.isNotEmpty() == true) button.strokeColor = enabledStroke
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
packageManager.getPackageInfo(savedPackageName!!, PackageManager.PackageInfoFlags.of(0))
else
packageManager.getPackageInfo(savedPackageName!!, 0)
} catch (e: PackageManager.NameNotFoundException) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
e.printStackTrace()
}
/* listen on clicks */
binding.favGroup.addOnButtonCheckedListener { _: MaterialButtonToggleGroup?,
checkedId: Int, isChecked: Boolean ->
try {
if (checkedId == button.id) {
if (isChecked) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().putString(KEY_APP_NO_ + position, packageName).apply()
button.strokeColor = enabledStroke
} else {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
private fun appName() {
binding.appName.text = contactName
@ -187,195 +138,21 @@ internal class ContactMenu : BottomSheetDialogFragment() {
private fun detailedInfo() {
var intent = Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + packageName));
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + contactId));
startActivity(intent);
}
/* activity browser dialog */
private fun activityBrowser() {
val dialogBinding = ActivityBrowserDialogBinding.inflate(lActivity!!.layoutInflater)
val dialogBuilder = MaterialAlertDialogBuilder(lActivity!!)
.setView(dialogBinding.root)
.setPositiveButton(android.R.string.cancel, null)
.show()
/* show app name */
dialogBinding.appName.text = packageManager.getApplicationLabel(appInfo)
/* get activity info */
val activityInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(
packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong())
)
} else {
packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
private fun sendSms() {
var intent = Intent(Intent.ACTION_SEND);
intent.setData(Uri.parse("smsto:" + contactPhoneNumber));
startActivity(intent);
}
private fun callPhone() {
var intent = Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + contactPhoneNumber));
startActivity(intent);
}
/* show activity list */
val activityAdapter: ArrayAdapter<String> =
ArrayAdapter(requireContext(), R.layout.list_item, R.id.itemText, ArrayList())
if (activityInfo.activities.isNotEmpty()) {
for (activity in activityInfo.activities) {
activityAdapter.add(
activity.toString().split(" ").toTypedArray()[1].replace("}", "")
)
}
dialogBinding.activityList.adapter = activityAdapter
}
/* listen item clicks */
dialogBinding.activityList.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, i: Int, _: Long ->
try {
/* open activity */
val intent = Intent()
intent.component = ComponentName(packageName, activityAdapter.getItem(i).toString())
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
requireContext().startActivity(intent)
} catch (exception: Exception) {
/* couldn't open activity */
exception.printStackTrace()
val exceptionShort = (exception.toString().split(": ").toTypedArray())[0]
Toast.makeText(requireContext(),
"${resources.getString(R.string.unable_to_launch)} -\n$exceptionShort", Toast.LENGTH_LONG).show()
}
dialogBuilder.dismiss()
}
}
/* open app's page in app store/market */
private fun appStore() {
try {
val storeIntent = Intent(Intent.ACTION_VIEW)
storeIntent.data = Uri.parse("market://details?id=$packageName")
storeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(storeIntent)
} catch (activityNotFoundException: ActivityNotFoundException) {
/* no app store found exception */
Toast.makeText(requireContext(), requireContext().getString(R.string.null_app_store_message),
Toast.LENGTH_SHORT).show()
activityNotFoundException.printStackTrace()
}
this.dismiss()
}
/* launch app as a freeform window */
private fun freeform() {
val freeformIntent = requireContext().packageManager.getLaunchIntentForPackage(packageName)
freeformIntent!!.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
val rect = Rect(0, screenHeight / 2, screenWidth, screenHeight)
var activityOptions = activityOptions
activityOptions = activityOptions.setLaunchBounds(rect)
requireContext().startActivity(freeformIntent, activityOptions.toBundle())
this.dismiss()
}
/* open android's app info screen */
private fun appInfo() {
val infoIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
infoIntent.data = Uri.parse("package:$packageName")
infoIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(infoIntent)
this.dismiss()
}
private fun share() {
try {
// Create a temporary file to copy the APK
val apkLabel = packageManager.getApplicationLabel(appInfo).toString().lowercase().replace(" ", "_")
val tempApkFile = File(requireContext().externalCacheDir, "$apkLabel.apk")
// Copy the APK file
FileInputStream(File(appInfo.sourceDir)).use { `in` ->
FileOutputStream(tempApkFile).use { out ->
val buffer = ByteArray(1024)
var length: Int
while (`in`.read(buffer).also { length = it } > 0) {
out.write(buffer, 0, length)
}
}
}
// Generate a content URI using FileProvider
val contentUri =
FileProvider.getUriForFile(requireContext(), "${requireContext().packageName}.fileprovider", tempApkFile)
//requireContext().grantUriPermission(receivers.package.name, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
// Create a Share Intent
Intent(Intent.ACTION_SEND).apply {
type = "application/vnd.android.package-archive"
putExtra(Intent.EXTRA_STREAM, contentUri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}.let {
// Start the chooser activity
startActivity(Intent.createChooser(it, getString(R.string.share_apk_message)))
}
}
catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() }
catch (e: IOException) { e.printStackTrace() }
this.dismiss()
}
/* uninstall the app */
private fun uninstall() {
val uninstallIntent = Intent(Intent.ACTION_DELETE)
uninstallIntent.data = Uri.parse("package:$packageName")
uninstallIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(uninstallIntent)
this.dismiss()
}
/* create and add an outlined button to the toggle group */
private val outlinedButton: MaterialButton get() {
val style = com.google.android.material.R.attr.materialButtonOutlinedStyle
val button = MaterialButton(requireContext(), null, style)
button.layoutParams = LinearLayoutCompat.LayoutParams(
LinearLayoutCompat.LayoutParams.WRAP_CONTENT,
LinearLayoutCompat.LayoutParams.WRAP_CONTENT, 1F
)
binding.favGroup.addView(button)
return button
}
/* long value to local date-time format */
private fun dateTimeFormat(long: Long) : String = SimpleDateFormat.getDateTimeInstance().format(Date(long))
/* get and arrange all the permissions for an application */
private val permissionsList : String get() {
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_PERMISSIONS.toLong()))
} else {
packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS)
}
return if (packageInfo.requestedPermissions.isNotEmpty()) {
val stringBuilder = StringBuilder()
packageInfo.requestedPermissions.indices.forEach { i: Int ->
if (i != packageInfo.requestedPermissions.size - 1)
stringBuilder.append("${packageInfo.requestedPermissions[i]}\n\n")
/* don't add any new line after the last entry */
else
stringBuilder.append(packageInfo.requestedPermissions[i])
}
stringBuilder.toString()
} else {
""
}
}
/* get activity options for launching app in freeform mode */
private val activityOptions: ActivityOptions get() {
val activityOptions = ActivityOptions.makeBasic()
try {
val method =
ActivityOptions::class.java.getMethod("setLaunchWindowingMode", Int::class.javaPrimitiveType)
method.invoke(activityOptions, 5)
} catch (exception: Exception) {
exception.printStackTrace()
}
return activityOptions
}
}

View File

@ -152,9 +152,10 @@ internal class RssItemAdapter (
}.dispatchUpdatesTo(this).apply {
val visibleItemCount = (layoutManager?.findLastVisibleItemPosition() ?: 0) - (layoutManager?.findFirstVisibleItemPosition() ?: 0)
val first = layoutManager?.findLastVisibleItemPosition() ?: 0
if (visibleItemCount > 0) {
this@RssItemAdapter.notifyItemRangeChanged(0, visibleItemCount)
recyclerView?.scrollToPosition(0)
this@RssItemAdapter.notifyItemRangeChanged(first, visibleItemCount)
// recyclerView?.scrollToPosition(0)
}
}
rssDataItemLis.clear()

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M309.5,494.1c-1.9,0 -3.5,0.3 -4.7,0.8 1.6,-0.5 3.4,-0.8 5.2,-0.8h-0.5zM845.1,707.5c0.1,-1 0.2,-2 0.4,-2.9 -0.2,0.4 -0.3,1.4 -0.4,2.9zM880.9,313.3c0,-0 0,-0.1 0,-0.1v-0.5c0,0.2 0,0.4 -0,0.6zM845.1,313.2c0,0 0,0.1 0,0.1 -0,-0.2 -0,-0.4 -0,-0.6v0.5zM866.7,849.4a348,348 0,0 0,-32.7 -107.5c-3.3,-6.6 -6.7,-13.1 -10.4,-19.5a0.2,0.2 0,0 0,-0 -0.1c-15.9,-26.9 -35.3,-51.8 -58,-74.1l-0,-0c-4.9,-4.8 -10,-9.6 -15.2,-14.1 -37.3,-32.7 -80.3,-56.9 -126.3,-71.7 8.3,-4.6 16.4,-9.8 24.1,-15.5 8.8,-6.5 17.2,-13.7 25,-21.5 41.4,-41.4 64.2,-96.4 64.2,-155 0,-58.5 -22.8,-113.6 -64.2,-155 -40.6,-40.6 -94.4,-63.3 -151.8,-64.2 -0.9,-0 -1.8,-0 -2.7,-0 -0.9,0 -1.8,0 -2.7,0 -57.3,0.8 -111.1,23.5 -151.8,64.2 -41.4,41.4 -64.2,96.4 -64.2,155 0,58.5 22.8,113.6 64.2,155 7.9,7.9 16.2,15.1 25,21.5 7.7,5.7 15.8,10.9 24.1,15.5 -45.9,14.7 -89,39 -126.3,71.7 -5.2,4.6 -10.3,9.3 -15.2,14.1 -22.7,22.3 -42.2,47.2 -58,74.1 -3.7,6.4 -7.1,12.9 -10.4,19.5a348,348 0,0 0,-32.7 107.5c-1.6,12 6.8,23 18.8,24.6 1,0.1 2,0.2 3,0.2 0.9,0 1.8,-0.1 2.6,-0.2 8.7,-1.9 15.7,-9 17,-18.3 10.1,-69.3 43.1,-132.3 90.6,-180.3 56.4,-57 133.1,-92.7 216,-92.9h0.5c82.7,0.3 159.3,36 215.5,92.9 47.5,48 80.5,111 90.6,180.3 1.4,9.3 8.3,16.3 17,18.2 0,0 0,0 0.1,0 0.9,0.1 1.7,0.2 2.6,0.2 1,0 2,-0.1 3,-0.2 12,-1.6 20.4,-12.6 18.8,-24.6zM518.2,545.9c-0.4,0 -0.9,0 -1.3,-0 -81.8,-0.6 -154.7,-57.4 -174.7,-133.7 -0.2,-0.8 -0.4,-1.7 -0.6,-2.5 -3.1,-12.6 -4.8,-25.7 -4.8,-39.2s1.7,-26.7 4.8,-39.5c0.2,-0.9 0.4,-1.7 0.6,-2.6 20,-78.1 93.7,-140.3 176,-140.3h0.9c82.3,0 155.9,62.1 176,140.3 0.2,0.9 0.4,1.7 0.6,2.6 3.1,12.8 4.8,26.1 4.8,39.5 0,13.4 -1.7,26.5 -4.8,39.2 -0.2,0.8 -0.4,1.7 -0.6,2.5 -19.9,76.2 -92.9,133.1 -174.7,133.7 -0.8,0 -1.5,0 -2.3,0z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M885.7,741.4L515,741.4l-105.4,105.4c-0.8,0.8 -1.8,1.1 -2.6,1.7 -0.8,0.6 -1.3,1.4 -2.2,1.9 -0.4,0.2 -0.9,0.2 -1.3,0.4 -1.5,0.7 -3.1,1.2 -4.7,1.5 -1.2,0.3 -2.4,0.6 -3.6,0.7 -1.6,0.1 -3,-0.1 -4.6,-0.3 -1.4,-0.2 -2.7,-0.3 -4,-0.8 -1.2,-0.4 -2.3,-1 -3.4,-1.6 -1.6,-0.8 -3,-1.7 -4.3,-2.9 -0.3,-0.3 -0.8,-0.4 -1.1,-0.7 -0.5,-0.5 -0.7,-1.3 -1.2,-1.8 -0.7,-0.9 -1.7,-1.5 -2.3,-2.5L314.3,741.4L169.8,741.4c-49.4,0 -89.5,-40.1 -89.5,-89.5L80.4,226.9c0,-49.4 40.1,-89.5 89.5,-89.5h715.9c49.4,0 89.5,40.1 89.5,89.5v425.1c0,49.4 -40.1,89.5 -89.5,89.5zM307.1,729.3c-1.2,-2.1 -1.8,-4.3 -2.3,-6.5 0.6,3.5 1.9,6.6 3.9,9.3l-1.6,-2.8zM312,702.3c-0.6,0.5 -1.2,0.9 -1.7,1.5 0.5,-0.5 1.2,-1 1.7,-1.5zM304.3,720.2c-0.1,-1.2 0.2,-2.3 0.3,-3.5 -0.1,0.8 -0.5,1.5 -0.5,2.4 0,0.4 0.2,0.7 0.2,1.1zM306.6,709.2c-0.3,0.6 -0.7,1.2 -0.9,1.8 0.2,-0.6 0.6,-1.2 0.9,-1.8zM930.5,226.9c0,-24.7 -20,-44.7 -44.7,-44.7L169.8,182.1c-24.7,0 -44.7,20 -44.7,44.7L125.1,651.9c0,24.7 20,44.7 44.7,44.7h156.6c-0.3,0 -0.6,0.2 -0.9,0.2 8,-0.3 16,3.3 20.3,10.6l51.8,87.4 91.7,-91.8c4.6,-4.6 10.7,-6.7 16.7,-6.5h379.7c24.7,0 44.7,-20 44.7,-44.7L930.5,226.9zM317,698.9c0.9,-0.4 1.8,-0.6 2.7,-0.9 -0.9,0.3 -1.9,0.5 -2.7,0.9zM729.1,473c-24.7,0 -44.7,-20 -44.7,-44.7 0,-24.7 20,-44.7 44.7,-44.7 24.7,0 44.7,20 44.7,44.7s-20,44.7 -44.7,44.7zM527.8,473c-24.7,0 -44.7,-20 -44.7,-44.7 0,-24.7 20,-44.7 44.7,-44.7s44.7,20 44.7,44.7 -20,44.7 -44.7,44.7zM326.4,473c-24.7,0 -44.7,-20 -44.7,-44.7 0,-24.7 20,-44.7 44.7,-44.7s44.7,20 44.7,44.7 -20,44.7 -44.7,44.7z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M737.6,934.4c-342.4,0 -624.8,-258.4 -656.8,-600.8v-0.8c-0.8,-5.6 -1.6,-12.8 -2.4,-19.2 0,-4.8 -0.8,-10.4 -0.8,-14.4 0.8,-70.4 36,-135.2 95.2,-175.2 30.4,-20.8 66.4,-32.8 103.2,-34.4h12.8c63.2,0 123.2,28 163.2,76.8 44,52.8 58.4,123.2 40.8,192 -17.6,68 -69.6,121.6 -138.4,144l-22.4,7.2 14.4,18.4c63.2,80 140,143.2 228.8,188.8l18.4,9.6 4.8,-20c16,-72 80.8,-125.6 158.4,-129.6h8c94.4,0 173.6,72 181.6,164.8 2.4,25.6 -1.6,51.2 -9.6,76 -22.4,62.4 -77.6,107.2 -144,116.8 -4.8,0.8 -8.8,0.8 -13.6,1.6 -13.6,-2.4 -28,-1.6 -41.6,-1.6zM117.6,328c30.4,324 296.8,568 620,568 12.8,0 26.4,-0.8 40,-1.6h3.2c2.4,0 4.8,0 7.2,-0.8 52.8,-7.2 96,-43.2 114.4,-92 7.2,-19.2 9.6,-39.2 8,-60 -5.6,-72 -69.6,-130.4 -141.6,-130.4h-6.4c-62.4,4 -115.2,46.4 -130.4,105.6 -5.6,20.8 -27.2,36.8 -50.4,36.8 -8,0 -15.2,-1.6 -21.6,-4.8 -110.4,-56 -204.8,-140.8 -274.4,-244 -4,-5.6 -4,-12.8 -1.6,-18.4 3.2,-6.4 9.6,-11.2 16.8,-12 74.4,-4.8 139.2,-56 157.6,-125.6 15.2,-56.8 2.4,-115.2 -33.6,-158.4 -33.6,-40 -82.4,-63.2 -134.4,-63.2H280c-30.4,1.6 -60,12 -84.8,28.8 -48.8,32 -78.4,86.4 -78.4,144V312c-0.8,4.8 0,10.4 0.8,16z"
android:fillColor="#000000"/>
</vector>

View File

@ -8,37 +8,52 @@
android:clickable="true"
android:focusableInTouchMode="true">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/appNameInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:hintEnabled="false"
app:boxStrokeWidth="@dimen/zero"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<com.google.android.material.textfield.TextInputEditText
<TextView
android:id="@+id/appName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="@dimen/zero"
android:textSize="30dp"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"/>
<TextView
android:id="@+id/totalTouch"
android:layout_margin="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|left"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge" />
</com.google.android.material.textfield.TextInputLayout>
/>
<TextView
<com.google.android.material.button.MaterialButton
android:id="@+id/lastTouchDate"
android:layout_margin="20dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|right"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:id="@+id/appPackage"
style="@style/Widget.Material3.Button.TextButton"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
app:layout_constraintTop_toBottomOf="@id/totalTouch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appNameInputLayout" />
app:layout_constraintStart_toStartOf="parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/activityBrowser"
@ -68,10 +83,10 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appPackage" />
<com.google.android.material.button.MaterialButtonToggleGroup
<View
android:id="@+id/favGroup"
android:layout_width="@dimen/zero"
android:layout_height="wrap_content"
android:layout_height="1dp"
android:layout_marginTop="@dimen/eight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -17,12 +17,36 @@
app:layout_constraintRight_toRightOf="parent"
android:layout_height="wrap_content"
android:minWidth="@dimen/zero"
android:textSize="28dp"
android:gravity="center"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:id="@+id/totalTouch"
android:layout_margin="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|left"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:id="@+id/lastTouchDate"
android:layout_margin="20dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|right"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:textSize="30dp"
android:id="@+id/phoneNumber"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
@ -30,115 +54,48 @@
android:layout_marginTop="@dimen/eight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appName" />
app:layout_constraintTop_toBottomOf="@+id/totalTouch" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/activityBrowser"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_activity"
android:tooltipText="@string/activity_browser"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/detailedInfo"
app:layout_constraintTop_toBottomOf="@+id/phoneNumber" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
<LinearLayout
app:layout_constraintTop_toBottomOf="@id/phoneNumber"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<rasel.lunar.launcher.view.CircleImageView
app:civ_circle_background_color="#77FFFFFF"
app:civ_border_width="8dp"
app:civ_border_color="#77FFFFFF"
android:adjustViewBounds="true"
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/detailedInfo"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_info"
android:tooltipText="@string/detailed_info"
app:layout_constraintEnd_toStartOf="@id/activityBrowser"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/phoneNumber" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/favGroup"
android:layout_width="@dimen/zero"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detailedInfo"
app:singleSelection="true" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appInfo"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_info2"
android:tooltipText="@string/app_info"
app:layout_constraintEnd_toStartOf="@id/appFreeform"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appFreeform"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_pip"
android:tooltipText="@string/freeform"
app:layout_constraintEnd_toStartOf="@id/appStore"
app:layout_constraintStart_toEndOf="@id/appInfo"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appStore"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_store"
android:tooltipText="@string/app_store"
app:layout_constraintEnd_toStartOf="@id/appShare"
app:layout_constraintStart_toEndOf="@id/appFreeform"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appShare"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_share"
android:tooltipText="@string/share"
app:layout_constraintEnd_toStartOf="@id/appUninstall"
app:layout_constraintStart_toEndOf="@id/appStore"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appUninstall"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_delete"
android:tooltipText="@string/uninstall"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/appShare"
app:layout_constraintTop_toBottomOf="@+id/favGroup"
app:tint="@android:color/holo_red_light" />
android:layout_margin="@dimen/eight"
android:src="@drawable/contact"
/>
<rasel.lunar.launcher.view.CircleImageView
app:civ_circle_background_color="#77FFFFFF"
app:civ_border_width="8dp"
app:civ_border_color="#77FFFFFF"
android:adjustViewBounds="true"
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/sms"
android:layout_margin="@dimen/eight"
android:src="@drawable/message"
/>
<rasel.lunar.launcher.view.CircleImageView
app:civ_circle_background_color="#77FFFFFF"
app:civ_border_width="8dp"
app:civ_border_color="#77FFFFFF"
android:adjustViewBounds="true"
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/call"
android:layout_margin="@dimen/eight"
android:src="@drawable/phonecall"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>