Skip to content
This repository was archived by the owner on Jun 8, 2024. It is now read-only.

Commit c64b964

Browse files
committed
Category: Completed
Signed-off-by: Fung Gwo <[email protected]>
1 parent dc02a63 commit c64b964

24 files changed

+1064
-101
lines changed

mobile/src/main/kotlin/info/papdt/express/helper/Constants.kt

+1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ const val ACTION_REQUEST_DELETE_PACK = "$ACTION_PREFIX.REQUEST_DELETE_PACK"
1919

2020
const val EXTRA_PREFIX = BuildConfig.APPLICATION_ID + ".extra"
2121
const val EXTRA_DATA = "$EXTRA_PREFIX.DATA"
22+
const val EXTRA_OLD_DATA = "$EXTRA_PREFIX.OLD_DATA"
2223

2324
const val CHANNEL_ID_PACKAGE_STATUS = "package_status"
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,82 @@
11
package info.papdt.express.helper.dao
22

3+
import android.content.Context
34
import androidx.room.*
45
import androidx.room.OnConflictStrategy.*
6+
import info.papdt.express.helper.R
57
import info.papdt.express.helper.model.Category
68

79
@Dao
8-
interface CategoryDao {
10+
abstract class CategoryDao {
11+
12+
companion object {
13+
14+
private val DEFAULT_CATEGORIES_PAIRS = mapOf(
15+
R.string.default_category_art to "insert_photo",
16+
R.string.default_category_books to "book",
17+
R.string.default_category_daily_necessities to "home",
18+
R.string.default_category_digital_product to "phonelink",
19+
R.string.default_category_entertainment to "games",
20+
R.string.default_category_food_snack to "restaurant_menu",
21+
R.string.default_category_home_appliance to "power",
22+
R.string.default_category_letters to "email"
23+
)
24+
25+
}
26+
27+
suspend fun add(title: String, iconCode: String): Category {
28+
return Category(title, iconCode).also { add(it) }
29+
}
930

1031
@Insert(onConflict = REPLACE)
11-
suspend fun add(category: Category)
32+
abstract suspend fun add(category: Category)
1233

1334
@Insert(onConflict = REPLACE)
14-
suspend fun addAll(categories: List<Category>)
35+
abstract suspend fun addAll(categories: List<Category>)
1536

1637
@Update(onConflict = REPLACE)
17-
suspend fun update(category: Category)
38+
abstract suspend fun update(category: Category)
1839

1940
@Query("SELECT * FROM category")
20-
suspend fun getAll(): List<Category>
41+
abstract suspend fun getAll(): List<Category>
2142

2243
@Query("SELECT * FROM category WHERE title = :title LIMIT 1")
23-
suspend fun get(title: String): Category?
44+
abstract suspend fun get(title: String): Category?
2445

2546
@Delete
26-
suspend fun delete(category: Category)
47+
abstract suspend fun delete(category: Category)
2748

2849
@Delete
29-
suspend fun delete(categories: List<Category>)
50+
abstract suspend fun delete(categories: List<Category>)
51+
52+
suspend fun clear() {
53+
delete(getAll())
54+
}
55+
56+
suspend fun deleteWithUpdatingPackages(context: Context, category: Category) {
57+
val packDatabase = PackageDatabase.getInstance(context)
58+
for (item in packDatabase.data) {
59+
if (item.categoryTitle == category.title) {
60+
item.categoryTitle = null
61+
}
62+
}
63+
packDatabase.save()
64+
delete(category)
65+
}
66+
67+
suspend fun clearWithUpdatingPackages(context: Context) {
68+
val packDatabase = PackageDatabase.getInstance(context)
69+
for (item in packDatabase.data) {
70+
item.categoryTitle = null
71+
}
72+
packDatabase.save()
73+
clear()
74+
}
75+
76+
suspend fun addDefaultCategories(context: Context) {
77+
for ((titleRes, iconCode) in DEFAULT_CATEGORIES_PAIRS) {
78+
add(context.getString(titleRes), iconCode)
79+
}
80+
}
3081

3182
}

mobile/src/main/kotlin/info/papdt/express/helper/event/EventCallbacks.kt

+62
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@ package info.papdt.express.helper.event
33
import android.content.BroadcastReceiver
44
import android.content.Context
55
import android.content.Intent
6+
import android.os.Parcelable
67
import android.util.Log
8+
import androidx.recyclerview.widget.RecyclerView
79
import info.papdt.express.helper.EXTRA_DATA
10+
import info.papdt.express.helper.EXTRA_OLD_DATA
11+
import info.papdt.express.helper.model.Category
812
import info.papdt.express.helper.model.Kuaidi100Package
13+
import info.papdt.express.helper.receiver.ActionBroadcastReceiver
14+
import info.papdt.express.helper.receiver.ActionBroadcastReceiver.Companion.create
15+
import me.drakeet.multitype.ItemViewBinder
916
import moe.feng.kotlinyan.common.get
17+
import kotlin.reflect.KClass
1018

1119
object EventCallbacks {
1220

@@ -24,4 +32,58 @@ object EventCallbacks {
2432
}
2533
}
2634

35+
fun onDeleteCategory(callback: (data: Category) -> Unit): BroadcastReceiver {
36+
return object : BroadcastReceiver() {
37+
override fun onReceive(context: Context, intent: Intent?) {
38+
if (intent == null || !intent.hasExtra(EXTRA_DATA)) {
39+
Log.e(TAG, "onDeleteCategory: receive empty data")
40+
return
41+
}
42+
callback(intent[EXTRA_DATA]!!.asParcelable())
43+
}
44+
}
45+
}
46+
47+
fun onSaveNewCategory(callback: (data: Category) -> Unit): BroadcastReceiver {
48+
return object : BroadcastReceiver() {
49+
override fun onReceive(context: Context, intent: Intent?) {
50+
if (intent == null || !intent.hasExtra(EXTRA_DATA)) {
51+
Log.e(TAG, "onSaveNewCategory: receive empty data")
52+
return
53+
}
54+
callback(intent[EXTRA_DATA]!!.asParcelable())
55+
}
56+
}
57+
}
58+
59+
fun onSaveEditCategory(
60+
callback: (oldData: Category, data: Category) -> Unit): BroadcastReceiver {
61+
return object : BroadcastReceiver() {
62+
override fun onReceive(context: Context, intent: Intent?) {
63+
if (intent == null
64+
|| !intent.hasExtra(EXTRA_DATA)
65+
|| !intent.hasExtra(EXTRA_OLD_DATA)) {
66+
Log.e(TAG, "onSaveEditCategory: receive empty data")
67+
return
68+
}
69+
callback(
70+
intent[EXTRA_OLD_DATA]!!.asParcelable(),
71+
intent[EXTRA_DATA]!!.asParcelable()
72+
)
73+
}
74+
}
75+
}
76+
77+
fun <T : Parcelable, VH : RecyclerView.ViewHolder, B: ItemViewBinder<T, VH>> onItemClick(
78+
clazz: KClass<B>,
79+
callback: (data: T?) -> Unit): BroadcastReceiver {
80+
return create(EventIntents.getItemOnClickActionName(clazz)) { _, intent ->
81+
if (intent == null || !intent.hasExtra(EXTRA_DATA)) {
82+
Log.e(TAG, "onItemClick: receive empty data")
83+
return@create
84+
}
85+
callback(intent[EXTRA_DATA]?.asParcelable())
86+
}
87+
}
88+
2789
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,58 @@
11
package info.papdt.express.helper.event
22

33
import android.content.Intent
4+
import android.os.Parcelable
5+
import androidx.recyclerview.widget.RecyclerView
6+
import info.papdt.express.helper.ACTION_PREFIX
47
import info.papdt.express.helper.ACTION_REQUEST_DELETE_PACK
58
import info.papdt.express.helper.EXTRA_DATA
9+
import info.papdt.express.helper.EXTRA_OLD_DATA
10+
import info.papdt.express.helper.model.Category
611
import info.papdt.express.helper.model.Kuaidi100Package
12+
import me.drakeet.multitype.ItemViewBinder
13+
import kotlin.reflect.KClass
714

815
object EventIntents {
916

17+
const val ACTION_REQUEST_DELETE_CATEGORY = "$ACTION_PREFIX.REQUEST_DELETE_CATEGORY"
18+
const val ACTION_SAVE_NEW_CATEGORY = "$ACTION_PREFIX.SAVE_NEW_CATEGORY"
19+
const val ACTION_SAVE_EDIT_CATEGORY = "$ACTION_PREFIX.SAVE_EDIT_CATEGORY"
20+
1021
fun requestDeletePackage(data: Kuaidi100Package): Intent {
1122
val intent = Intent(ACTION_REQUEST_DELETE_PACK)
1223
intent.putExtra(EXTRA_DATA, data)
1324
return intent
1425
}
1526

27+
fun requestDeleteCategory(data: Category): Intent {
28+
val intent = Intent(ACTION_REQUEST_DELETE_CATEGORY)
29+
intent.putExtra(EXTRA_DATA, data)
30+
return intent
31+
}
32+
33+
fun saveNewCategory(data: Category): Intent {
34+
val intent = Intent(ACTION_SAVE_NEW_CATEGORY)
35+
intent.putExtra(EXTRA_DATA, data)
36+
return intent
37+
}
38+
39+
fun saveEditCategory(oldData: Category, data: Category): Intent {
40+
val intent = Intent(ACTION_SAVE_EDIT_CATEGORY)
41+
intent.putExtra(EXTRA_OLD_DATA, oldData)
42+
intent.putExtra(EXTRA_DATA, data)
43+
return intent
44+
}
45+
46+
fun <T, VH : RecyclerView.ViewHolder, B: ItemViewBinder<T, VH>>
47+
getItemOnClickActionName(clazz: KClass<B>): String {
48+
return clazz::java.name + ".ACTION_ON_CLICK"
49+
}
50+
51+
fun <T : Parcelable, VH : RecyclerView.ViewHolder, B: ItemViewBinder<T, VH>>
52+
notifyItemOnClick(clazz: KClass<B>, data: T?): Intent {
53+
val intent = Intent(getItemOnClickActionName(clazz))
54+
intent.putExtra(EXTRA_DATA, data)
55+
return intent
56+
}
57+
1658
}

mobile/src/main/kotlin/info/papdt/express/helper/model/Category.kt

+9-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ import androidx.room.PrimaryKey
99
@Entity
1010
data class Category(
1111
@PrimaryKey var title: String,
12-
@ColumnInfo(name = "icon_name") var iconCode: String? = null
13-
) : Parcelable {
12+
@ColumnInfo(name = "icon_name") var iconCode: String = "archive"
13+
) : Parcelable, Comparable<Category> {
14+
15+
constructor(src: Category): this(src.title, src.iconCode)
16+
17+
override fun compareTo(other: Category): Int {
18+
return title.compareTo(other.title)
19+
}
1420

1521
companion object {
1622

@@ -29,7 +35,7 @@ data class Category(
2935

3036
constructor(parcel: Parcel) : this(
3137
parcel.readString()!!,
32-
parcel.readString()
38+
parcel.readString()!!
3339
)
3440

3541
override fun writeToParcel(parcel: Parcel, flags: Int) = with(parcel) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package info.papdt.express.helper.receiver
2+
3+
import android.content.BroadcastReceiver
4+
import android.content.Context
5+
import android.content.Intent
6+
import android.content.IntentFilter
7+
import androidx.localbroadcastmanager.content.LocalBroadcastManager
8+
9+
abstract class ActionBroadcastReceiver(val intentFilter: IntentFilter) : BroadcastReceiver() {
10+
11+
companion object {
12+
13+
inline fun create(intentFilter: IntentFilter,
14+
crossinline block: (context: Context, intent: Intent?) -> Unit)
15+
: ActionBroadcastReceiver {
16+
return object : ActionBroadcastReceiver(intentFilter) {
17+
override fun onReceive(context: Context, intent: Intent?) {
18+
block(context, intent)
19+
}
20+
}
21+
}
22+
23+
inline fun create(action: String,
24+
crossinline block: (context: Context, intent: Intent?) -> Unit)
25+
: ActionBroadcastReceiver {
26+
return create(IntentFilter(action), block)
27+
}
28+
29+
}
30+
31+
fun registerLocal(localBroadcastManager: LocalBroadcastManager) {
32+
localBroadcastManager.registerReceiver(this, intentFilter)
33+
}
34+
35+
fun unregisterLocal(localBroadcastManager: LocalBroadcastManager) {
36+
localBroadcastManager.unregisterReceiver(this)
37+
}
38+
39+
fun register(context: Context) {
40+
context.registerReceiver(this, intentFilter)
41+
}
42+
43+
fun unregister(context: Context) {
44+
context.unregisterReceiver(this)
45+
}
46+
47+
}

mobile/src/main/kotlin/info/papdt/express/helper/ui/DetailsActivity.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import info.papdt.express.helper.model.BaseMessage
3131
import info.papdt.express.helper.model.Kuaidi100Package
3232
import info.papdt.express.helper.support.*
3333
import info.papdt.express.helper.ui.common.AbsActivity
34-
import info.papdt.express.helper.ui.fragment.dialog.EditPackageDialog
34+
import info.papdt.express.helper.ui.dialog.EditPackageDialog
3535
import info.papdt.express.helper.ui.items.DetailsStatusItemBinder
3636
import info.papdt.express.helper.ui.items.DetailsTwoLineItem
3737
import info.papdt.express.helper.ui.items.DetailsTwoLineItemBinder

mobile/src/main/kotlin/info/papdt/express/helper/ui/HomeActivity.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class HomeActivity : AbsActivity(), OnRefreshListener {
6262
const val STATE_TEMP_FILTER_COMPANY = "$TAG.temp_filter_company"
6363

6464
const val REQUEST_FILTER_COMPANY = 20001
65+
const val REQUEST_CODE_CHANGE = 20002
6566

6667
fun search(context: Context, number: String) {
6768
val intent = Intent(context, HomeActivity::class.java)
@@ -249,7 +250,7 @@ class HomeActivity : AbsActivity(), OnRefreshListener {
249250

250251
TooltipCompat.setTooltipText(manageCategoriesButton, getString(R.string.action_manage_categories))
251252
manageCategoriesButton.setOnClickListener {
252-
ManageCategoriesActivity.launch(this)
253+
ManageCategoriesActivity.launch(this, REQUEST_CODE_CHANGE)
253254
}
254255

255256
TooltipCompat.setTooltipText(scanButton, getString(R.string.activity_scanner))
@@ -453,6 +454,11 @@ class HomeActivity : AbsActivity(), OnRefreshListener {
453454
updateFilterCompanyChoiceText()
454455
}
455456
}
457+
REQUEST_CODE_CHANGE -> {
458+
if (RESULT_OK == resultCode) {
459+
listAdapter.notifyDataSetChanged()
460+
}
461+
}
456462
}
457463
}
458464

0 commit comments

Comments
 (0)