Skip to content

Commit 7ef2c96

Browse files
committed
refactor: redesigned home screen widget for android
As per issue #415
1 parent 71614cd commit 7ef2c96

35 files changed

+729
-260
lines changed

android/app/src/main/AndroidManifest.xml

+8-8
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@
6565

6666

6767
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
68-
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
69-
<intent-filter>
70-
<action android:name="android.intent.action.BOOT_COMPLETED"/>
71-
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
72-
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
73-
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
74-
</intent-filter>
75-
</receiver>
68+
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
69+
<intent-filter>
70+
<action android:name="android.intent.action.BOOT_COMPLETED"/>
71+
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
72+
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
73+
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
74+
</intent-filter>
75+
</receiver>
7676
</application>
7777
</manifest>

android/app/src/main/kotlin/com/ccextractor/taskwarrior/MainActivity.kt

-5
This file was deleted.

android/app/src/main/kotlin/com/example/taskwarrior/MainActivity.kt renamed to android/app/src/main/kotlin/com/ccextractor/taskwarriorflutter/MainActivity.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ package com.ccextractor.taskwarriorflutter
22

33
import io.flutter.embedding.android.FlutterActivity
44

5-
class MainActivity: FlutterActivity() {
6-
}
5+
class MainActivity: FlutterActivity()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package com.ccextractor.taskwarriorflutter
2+
import android.annotation.TargetApi
3+
import android.appwidget.AppWidgetManager
4+
import android.content.Context
5+
import android.net.Uri
6+
import android.widget.RemoteViews
7+
import es.antonborri.home_widget.HomeWidgetBackgroundIntent
8+
import es.antonborri.home_widget.HomeWidgetLaunchIntent
9+
import es.antonborri.home_widget.HomeWidgetProvider
10+
import es.antonborri.home_widget.HomeWidgetPlugin
11+
import org.json.JSONException
12+
import android.content.Intent
13+
import android.widget.RemoteViewsService
14+
import org.json.JSONObject
15+
import org.json.JSONArray as OrgJSONArray
16+
import android.os.Bundle
17+
import android.app.PendingIntent
18+
import android.appwidget.AppWidgetProvider
19+
import android.os.Build
20+
21+
22+
@TargetApi(Build.VERSION_CODES.CUPCAKE)
23+
class TaskWarriorWidgetProvider : AppWidgetProvider() {
24+
25+
override fun onReceive(context: Context, intent: Intent) {
26+
// val myaction = intent.action
27+
if (intent.action == "TASK_ACTION") {
28+
val extras = intent.extras
29+
if(extras!=null){
30+
val uuid = extras.getString("uuid")?:""
31+
val add_task = extras.getString("launchedFor")
32+
val host = if(add_task == "ADD_TASK"){context.getString(R.string.app_widget_add_clicked_uri)}else{context.getString(R.string.app_widget_card_clicked_uri)}
33+
val launchIntent = Intent(context, MainActivity::class.java).apply {
34+
action = context.getString(R.string.app_widget_launch_action)
35+
data = Uri.parse("$host?uuid=$uuid")
36+
flags = Intent. FLAG_ACTIVITY_NEW_TASK
37+
context?.startActivity(this)
38+
}
39+
// HomeWidgetLaunchIntent.getActivity(context, MainActivity::class.java, Uri.parse("TaskWarrior://taskView?taskId=$uuid"))
40+
}
41+
}
42+
super.onReceive(context, intent)
43+
}
44+
fun getLayoutId(context: Context) : Int{
45+
val sharedPrefs = HomeWidgetPlugin.getData(context)
46+
val theme = sharedPrefs.getString("themeMode", "")
47+
val layoutId = if (theme.equals("dark")) {
48+
R.layout.taskwarrior_layout_dark // Define a dark mode layout in your resources
49+
} else {
50+
R.layout.taskwarrior_layout
51+
}
52+
return layoutId
53+
}
54+
@TargetApi(Build.VERSION_CODES.DONUT)
55+
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
56+
appWidgetIds.forEach { widgetId ->
57+
val sharedPrefs = HomeWidgetPlugin.getData(context)
58+
val tasks = sharedPrefs.getString("tasks", "")
59+
val intent = Intent(context, ListViewRemoteViewsService::class.java).apply {
60+
putExtra("tasksJsonString", tasks)
61+
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
62+
}
63+
val views = RemoteViews(context.packageName, getLayoutId(context)).apply {
64+
val pendingIntent: PendingIntent = HomeWidgetLaunchIntent.getActivity(
65+
context,
66+
MainActivity::class.java
67+
)
68+
setOnClickPendingIntent(R.id.logo, pendingIntent)
69+
val intent_for_add = Intent(context, TaskWarriorWidgetProvider::class.java).apply {
70+
setAction("TASK_ACTION")
71+
data=Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
72+
putExtra("launchedFor", "ADD_TASK")
73+
}
74+
val pendingIntentAdd: PendingIntent = PendingIntent.getBroadcast(
75+
context,
76+
0, // requestCode, can be any unique integer
77+
intent_for_add,
78+
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT or Intent.FILL_IN_COMPONENT // Use appropriate flags
79+
)
80+
setOnClickPendingIntent(R.id.add_btn, pendingIntentAdd)
81+
setRemoteAdapter(R.id.list_view, intent)
82+
}
83+
84+
val clickPendingIntent: PendingIntent = Intent(
85+
context,
86+
TaskWarriorWidgetProvider::class.java
87+
).run {
88+
setAction("TASK_ACTION")
89+
setIdentifier("uuid")
90+
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
91+
92+
PendingIntent.getBroadcast(
93+
context,
94+
0,
95+
this,
96+
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT or Intent.FILL_IN_COMPONENT
97+
)
98+
}
99+
100+
views.setPendingIntentTemplate(R.id.list_view, clickPendingIntent)
101+
appWidgetManager.updateAppWidget(widgetId, views)
102+
}
103+
super.onUpdate(context, appWidgetManager, appWidgetIds)
104+
}
105+
}
106+
class ListViewRemoteViewsFactory(
107+
private val context: Context,
108+
private val tasksJsonString: String?
109+
) : RemoteViewsService.RemoteViewsFactory {
110+
111+
private val tasks = mutableListOf<Task>()
112+
113+
override fun onCreate() {}
114+
115+
override fun onDataSetChanged() {
116+
if (tasksJsonString != null) {
117+
try {
118+
val jsonArray = OrgJSONArray(tasksJsonString as String)
119+
for (i in 0 until jsonArray.length()) {
120+
tasks.add(Task.fromJson(jsonArray.getJSONObject(i)))
121+
}
122+
} catch (e: JSONException) {
123+
e.printStackTrace()
124+
}
125+
}
126+
}
127+
128+
override fun onDestroy() {}
129+
130+
override fun getCount(): Int = tasks.size
131+
132+
fun getListItemLayoutId(): Int{
133+
val sharedPrefs = HomeWidgetPlugin.getData(context)
134+
val theme = sharedPrefs.getString("themeMode", "")
135+
val layoutId = if (theme.equals("dark")) {
136+
R.layout.listitem_layout_dark // Define a dark mode layout in your resources
137+
} else {
138+
R.layout.listitem_layout
139+
}
140+
return layoutId
141+
}
142+
fun getListItemLayoutIdForR1(): Int{
143+
val sharedPrefs = HomeWidgetPlugin.getData(context)
144+
val theme = sharedPrefs.getString("themeMode", "")
145+
val layoutId = if (theme.equals("dark")) {
146+
R.layout.no_tasks_found_li_dark // Define a dark mode layout in your resources
147+
} else {
148+
R.layout.no_tasks_found_li
149+
}
150+
return layoutId
151+
}
152+
fun getDotIdByPriority(p: String) : Int{
153+
println("PRIORITY: "+p)
154+
if(p.equals("L")) return R.drawable.low_priority_dot
155+
if(p.equals("M")) return R.drawable.mid_priority_dot
156+
if(p.equals("H")) return R.drawable.high_priority_dot
157+
return R.drawable.no_priority_dot
158+
}
159+
160+
override fun getViewAt(position: Int): RemoteViews {
161+
val task = tasks[position]
162+
if(task.uuid.equals("NO_TASK"))
163+
return RemoteViews(context.packageName, getListItemLayoutIdForR1()).apply {
164+
if(task.priority.equals("1"))
165+
setTextViewText(R.id.tv, "No tasks added yet")
166+
if(task.priority.equals("2"))
167+
setTextViewText(R.id.tv, "Filters applied are hiding all tasks")
168+
}
169+
return RemoteViews(context.packageName, getListItemLayoutId()).apply {
170+
setTextViewText(R.id.todo__title, task.title)
171+
setImageViewResource(R.id.dot, getDotIdByPriority(task.priority))
172+
val a = Intent().apply {
173+
174+
Bundle().also { extras ->
175+
extras.putString("action", "show_task")
176+
extras.putString("uuid", tasks[position].uuid)
177+
putExtras(extras)
178+
}
179+
180+
}
181+
setOnClickFillInIntent(R.id.list_item_container,a)
182+
}
183+
184+
}
185+
override fun getLoadingView(): RemoteViews? = null
186+
187+
override fun getViewTypeCount(): Int = 1
188+
189+
override fun getItemId(position: Int): Long = position.toLong()
190+
191+
override fun hasStableIds(): Boolean = true
192+
}
193+
class ListViewRemoteViewsService : RemoteViewsService() {
194+
195+
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
196+
val tasksJsonString = intent.getStringExtra("tasksJsonString")
197+
return ListViewRemoteViewsFactory(applicationContext, tasksJsonString)
198+
}
199+
}
200+
data class Task(val title: String, val urgencyLevel: String,val uuid:String, val priority: String) {
201+
companion object {
202+
fun fromJson(json: JSONObject): Task {
203+
val title = json.optString("description", "")
204+
val urgencyLevel = json.optString("urgency", "")
205+
val uuid = json.optString("uuid","")
206+
val priority = json.optString("priority", "")
207+
return Task(title, urgencyLevel, uuid, priority)
208+
}
209+
}
210+
}

android/app/src/main/kotlin/com/example/taskwarrior/TaskWarriorWidgetProvider.kt

-147
This file was deleted.

0 commit comments

Comments
 (0)