plusonelabs / calendar-widget

An calender widget for your Android home screen.
Apache License 2.0
369 stars 126 forks source link

Task (TODO) support #308

Closed ekalin closed 5 years ago

ekalin commented 5 years ago

Like other people, I like this widget, but I really want a widget that displays calendar events and tasks (or TODOs) together. Like Pure Calendar Widget does (or did), but unfortunately it's not working reliably lately and it seems not to be maintained anymore.

I read the previous issues about this topic, including the differently colored past events, but I find that solution unappealing.

Unfortunately, Android does have a concept of tasks as it does of calendar events. So it's not possible to have an universal solution that would just work with any of the dozens of Task applications available on the Play Store. Instead, code needs to be added for each application that would be supported by the widget.

I'm opening this new issue because I'm willing to write this code, if you'd be interested in including it in your app. Initially I'd add support for Samsung Calendar (because that's what I use and I've already reverse engineered how to fetch its tasks), but I'd try to write the code in a way that it should be simple to add support for other application. Another that comes to mind is https://github.com/dmfs/opentasks, it's open source and it's interfaces are available.

Anyway, let me know if you think this would be a nice addition to this widget.

yvolk commented 5 years ago

@ekalin I simplified and unified permissions checking and requesting. Tested this working on an emulator (see the commit https://github.com/andstatus/todoagenda/commit/3b76f99e8e0c22088518109ec8c571503bc455c8 ) I tested tasks with Open Tasks app https://f-droid.org/en/packages/org.dmfs.tasks/ What needs to be fixed yet:

  1. Days from today aren't shown for tasks in the "Event entry layout" = "All in one row"
  2. List of tasks in the Widget is not updated after its update in the "Open Tasks" application. We need to figure out, if there is any notification (Intent) sent by the Open Tasks app on the tasks update.
  3. For some reason, a task with a Start day of July 16 is shown as today's event, see the screenshot: Screenshot_1563116702
ekalin commented 5 years ago

This unified permission system does not work if the user does not have OpenTasks installed. Since no app created org.dmfs.permission.READ_TASKS, it can never be granted, and the app will be forever stuck in the needs permissions state. I guess it could be worked around by checking whether the application is installed.

But even so, I don't like this solution. Imagine support is added for several Task apps (there are many on Google Play), and each defines its own custom permission; at each refresh the widget would loop for all those permissions (or checking if the app is installed), when at most one task source is active at a time.

It is also not impossible that an user has a tasks app but does not want tasks in Todo Agenda. With your commit the widget only works if the user grants permissions to read tasks, even if he doesn't want that.

I think my solution was very nice: once the user selects the task source, if it requires permissions, a button to grant them is displayed, and once granted it is not displayed anymore. It would also work nicely should the user decide to switch to another task app, once he selects the new app from the list, the button would appear again to grant this new app's permissions.


I'm not sure what you mean by your comment #1. I've tested with "All in one row", and while the layout is somewhat ugly (the task text should probably be moved to right to align with the event text), otherwise everything seems to work normally.


As for point #2, I'm not really considering start dates, only due dates. Not all providers support this concept (Samsung Tasks does not, tasks in Google Calendar also do not, etc). But I suppose it could be added when it exists, though I'm not 100% sure of what it's semantics should be. Perhaps if there is a Due Date, display the task in that day. If there's a Start Date but not Due Date, display the task in the Start Date day. (Even before working with this widget, I myself never felt the need to have a "Start date" in my tasks.)

yvolk commented 5 years ago

This unified permission system does not work if the user does not have OpenTasks installed. Since no app created org.dmfs.permission.READ_TASKS, it can never be granted, and the app will be forever stuck in the needs permissions state. I guess it could be worked around by checking whether the application is installed.

I tested this case (when Open Tasks is not installed) on Android 9 emulator, and it works perfectly: the Open Tasks permission is simply ignored and a User is not prompted for the permission. Need to check on other versions though...

But even so, I don't like this solution. Imagine support is added for several Task apps (there are many on Google Play), and each defines its own custom permission; at each refresh the widget would loop for all those permissions (or checking if the app is installed), when at most one task source is active at a time.

The ToDo Agenda app is not for geeks. Ordinary user, I think, cares more about trusting an application than about cherry picking permissions :-) As for me personally, I don't see a reason to give an app permission to read my Calendars and not give a permission to read my tasks.

I'm not sure what you mean by your comment #1. I've tested with "All in one row", and while the layout is somewhat ugly (the task text should probably be moved to right to align with the event text), otherwise everything seems to work normally.

When you turn off day headers, the "All in one row" layout has additional column showing a number of days to the event start. Tasks event doesn't show anything in this column.

As for point #2, I'm not really considering start dates, only due dates. Not all providers support this concept (Samsung Tasks does not, tasks in Google Calendar also do not, etc). But I suppose it could be added when it exists, though I'm not 100% sure of what it's semantics should be. Perhaps if there is a Due Date, display the task in that day. If there's a Start Date but not Due Date, display the task in the Start Date day. (Even before working with this widget, I myself never felt the need to have a "Start date" in my tasks.)

It's strange for me that someone doesn't care when a task execution should be started ( if the date is set, of course). I think that for the purposes of this widget, if the start date of the task isn't set (e.g. because it's not supported by the Tasks app), the end/due date should be assumed as the start date.

ekalin commented 5 years ago

I tested this case (when Open Tasks is not installed) on Android 9 emulator, and it works perfectly: the Open Tasks permission is simply ignored and a User is not prompted for the permission. Need to check on other versions though...

I believe that's the version I used to test. Maybe you need to uninstall OpenTasks and TODO Agenda, and then install TODO Agenda.

The permission request is ignored and there is no prompt, but ContextCompat.checkSelfPermission returns that permission is not granted, and thus the widget is stuck in "needs permission"

When you turn off day headers, the "All in one row" layout has additional column showing a number of days to the event start. Tasks event doesn't show anything in this column.

I see, I had not tested "All in one row" and "No day headers". I'll emulate the layout.

It's strange for me that someone doesn't care when a task execution should be started ( if the date is set, of course).

Well, to say the truth I don't think start date makes much sense in tasks... Not in conjunction with due date. But since some task apps have this concept, I'll implement the logic I described in a previous commit.

yvolk commented 5 years ago

I tested this case (when Open Tasks is not installed) on Android 9 emulator, and it works perfectly: the Open Tasks permission is simply ignored and a User is not prompted for the permission. Need to check on other versions though...

I believe that's the version I used to test. Maybe you need to uninstall OpenTasks and TODO Agenda, and then install TODO Agenda.

The permission request is ignored and there is no prompt, but ContextCompat.checkSelfPermission returns that permission is not granted, and thus the widget is stuck in "needs permission"

Yes, current code in https://github.com/andstatus/todoagenda/commit/3b76f99e8e0c22088518109ec8c571503bc455c8 works normally only if "ToDo Agenda" is installed after tasks providing applications (or if such applications won't be installed at all).

The main feature that we need both for configuring Tasks and for checking / requesting their permissions is checking each "Events provider" if it's installed. Having this information we will:

  1. Check and request permissions for all installed "Event providers" and only for them.
  2. In the "Tasks" section of Settings we will list all installed "Tasks events providers" (just like we list Calendars in the "Calendars" section) and allow to check (select for viewing) any or all of them, and not only one Task provider, as is implemented now.

?!

ekalin commented 5 years ago

All in one layout is fixed here: https://github.com/ekalin/calendar-widget/commit/bf3a250986369d8bcfe293c60e1ae46d43d10d26

ekalin commented 5 years ago

The main feature that we need both for configuring Tasks and for checking / requesting their permissions is checking each "Events provider" if it's installed. Having this information we will:

  1. Check and request permissions for all installed "Event providers" and only for them.
  2. In the "Tasks" section of Settings we will list all installed "Tasks events providers" (just like we list Calendars in the "Calendars" section) and allow to check (select for viewing) any or all of them, and not only one Task provider, as is implemented now.

Seems to me like an overkill. I find it unlikely that someone would need more than one task application, and displaying tasks from multiple such applications at the same time. It would be adding extra complexity and code for a very small number of users.

One thing that I intend to do, though, is support selecting which task lists to display tasks from (same as the user can select calendars). I haven't started this yet, I'll fix the start date issue and any other problems first.

yvolk commented 5 years ago

The main feature that we need both for configuring Tasks and for checking / requesting their permissions is checking each "Events provider" if it's installed. Having this information we will:

  1. Check and request permissions for all installed "Event providers" and only for them.
  2. In the "Tasks" section of Settings we will list all installed "Tasks events providers" (just like we list Calendars in the "Calendars" section) and allow to check (select for viewing) any or all of them, and not only one Task provider, as is implemented now.

Seems to me like an overkill. I find it unlikely that someone would need more than one task application, and displaying tasks from multiple such applications at the same time. It would be adding extra complexity and code for a very small number of users.

Don't worry, I will do this myself :-) Actually I remember several requests telling that people use different calendar providers and different calendars on one device. One of common cases: calendars at work and personal calendars. So I think that this will be the same for tasks.

It's good that you decided to implement an option to select separate task lists. With our joint effort in Tasks section we will have for selection a list of all available "Task lists" from all task providers - exactly what we have in Calendars.

yvolk commented 5 years ago

@ekalin Thank you for improving tasks. I merged your PR #312 and added my fixes:

  1. Tasks really have startDate (and dueDate, of course), so I added both to the TaskEvent. Due date is not used so far and this is a problem that needs to be thought about. If both Start and Due dates set for the Task, and they are set at different days, this means that a User cares about these days. Currently this is ignored (only one date is taken into account)...

  2. Dates of a Task do have time, so I made sure that it is not cut off them. Unfortunately time is not shown yet. And this is another problem to solve. If you think that time is unimportant for tasks, we can think about an option for tasks like "Ignore time for Tasks"...

  3. Date range filtering should be the same both for Calendar events and for tasks. This is why I removed "special" end of period change for tasks. Whether "One day" range should include events up to end of tomorrow, is a separate question, not specific to tasks, and needs separate discussion.

Screenshot_1563602812

ekalin commented 5 years ago

Even though it won't make a difference, I have to disagree once more.

I think the most important date is the due date, not the start date. Well, actually I don't even see much reason for a start date in tasks. Same for time: I guess there might be situations when it makes sense. But when they start to get really similar to a calendar event, so perhaps a calendar event could be simply be used instead.

Of course, that is based on how I use tasks, which admittedly is quite simple and does not necessarily reflect how other users use them. But I just checked with Google Tasks (https://play.google.com/store/apps/details?id=com.google.android.apps.tasks), which would be a nice app to add suppport for (as it integrates with Google Calendar and the rest of the Google ecosystem), and it only has one date for tasks (it does have a time, though). In practice it doesn't matter whether we call the one date start or due, but semantically I'd argue for it being the due date, since a task is something that needs to be done, and generally needs to be done by some time.

Perhaps instead of releasing a super complete version, you could keep it simple for a first release, and if there is a lot of user feedback requesting support for task times, or dealing with tasks with start and and date, etc, then it could be added.

As for point 3, here I agree that consistency makes sense. I'd say that "One day" should include events (and tasks) up to the end of tomorrow (and not only the next 24 hours), but consistency is more important.

ekalin commented 5 years ago

Another thing occurred to me, considering the "calendarization" of tasks.

When dealing with past tasks, while your proposed changes still displays them, they appear in their respective days:

Screenshot_1563663148

While it might be useful (but by no means necessary) to highlight past tasks (with the background color), I find it completely irrelevant to know the exact date, and having them in separate days is counterproductive.

The solution I proposed simply showed past due tasks in "Today". By the way, the solution I propose is essentially what the not-maintained-anymore Pure Calendar Widget did, so there's at least one more person (that widget's author) that agrees with me on how tasks should behave in a widget :-) And I suppose several users of that widget were satisfied with how it worked.

I'd really like for you to not merge 1149fa94.

yvolk commented 5 years ago

I think the most important date is the due date, not the start date. Well, actually I don't even see much reason for a start date in tasks. Same for time: I guess there might be situations when it makes sense.

  1. There is no problem here: if you don't set Start Date, then Due Date is used by the widget, without a need for any changes in settings. Same for Time: I just checked that "Open Tasks" app allows to set "All day" checkbox for a task, so not only Start Date is optional, but even Time of the Due Date may be explicitly unset.

But when they start to get really similar to a calendar event, so perhaps a calendar event could be simply be used instead.

  1. I came to the same conclusion some years ago, before even joining this project. And I personally add my "Tasks" in the same Calendar app as other "calendar events". This is normal. Please read this discussion on "Completed" and "Cancelled" events: https://github.com/plusonelabs/calendar-widget/issues/126

Of course, that is based on how I use tasks, which admittedly is quite simple and does not necessarily reflect how other users use them. But I just checked with Google Tasks (https://play.google.com/store/apps/details?id=com.google.android.apps.tasks), which would be a nice app to add support for (as it integrates with Google Calendar and the rest of the Google ecosystem), and it only has one date for tasks (it does have a time, though). In practice it doesn't matter whether we call the one date start or due, but semantically I'd argue for it being the due date, since a task is something that needs to be done, and generally needs to be done by some time.

  1. As I wrote above, if some "Tasks" app doesn't have a notion of a "Start Date" OR it has, but a User didn't set the Start Date, Due Date is used by the widget instead. Point 1 in my previous comment is exactly about semantics: we shouldn't "rename" actual task properties or voluntary merge Start Date and Due Date into a "Task Date", meaning (semantics) of which somebody invented (no matter you or me...).

Perhaps instead of releasing a super complete version, you could keep it simple for a first release, and if there is a lot of user feedback requesting support for task times, or dealing with tasks with start and end date, etc, then it could be added.

  1. I understand you. You contribute to the project in order to make it suitable for your needs first. Good, why not? And I see that you understand my position also: I look at the new feature from a position of existing and future users, thousands of different users all around the world. I really don't want to receive tens of "bug reports" on the next day after a release telling me that I forgot about Start Date, time etc. - the things that are obvious even today and that are already supported for Calendar events. We are not in a hurry anyway. Are we? :-)

  2. Regarding showing due (past but incomplete) tasks. I think we need to invent a way, consistent with past (but shown according to settings...) Calendar events. Showing past events in "Today" is a dirty/ad hoc solution. Showing them under dedicated "Past and due" header would look nicer?! We could have an option "Show past/due events under one "Past and due" header" ?!

yvolk commented 5 years ago

I found another bug in Tasks: past tasks should have dedicated "past" color, but they are not now. BTW, look how I deal with day headers: I simply turn them off completely ;-) PastTaskBackgroundColor

ekalin commented 5 years ago

It went as predicted.

Just some small points to comment:

[Regarding start vs. due]

OpenTasks has a simple widget. If there's a start and due date, only the due date is displayed, and they are also sorted according to due date. So they seem to agree with me that due date should take priority, not start date.

And I personally add my "Tasks" in the same Calendar app as other "calendar events". This is normal. Please read this discussion on "Completed" and "Cancelled" events: #126

I've read that. Nice that it works for you, but to me (and I must assume some other people), while tasks and calendar events (especially an all-day event) are similar, there are some fundamental differences that prevent that solution:

understand you. You contribute to the project in order to make it suitable for your needs first. Good, why not?

I surely want it to at least accommodate my desires, but as I said, I was also emulating another widget that I had been using for years (https://play.google.com/store/apps/details?id=org.koxx.pure_calendar). And since it has a large number of downloads and a high review, so it's fair to suppose that others were satisfied with its model.

And I see that you understand my position also: I look at the new feature from a position of existing and future users, thousands of different users all around the world. I really don't want to receive tens of "bug reports" on the next day after a release telling me that I forgot about Start Date, time etc.

This can go both ways: if you release your way, next day you may receive tens of "bug reports" with concerns similar to what I'm raising here.

When in doubt, I'd go for the simpler solution first. If the users want more, it's easier to add complexity later than to remove it.

And as you said in the other bug report, you don't use tasks. Perhaps you should listen to how people that use them would like them. Unfortunately only you and I are taking part in this discussion, but support for tasks had been asked a couple times already.

On a general note, perhaps Open Tasks is not a good model for task behavior. It has too many features. If you look at other task apps, you'll see that on average they tend to have a simpler model for tasks.

yvolk commented 5 years ago

@ekalin It seems to me that you don't like what I'm doing because you are trying to mimic in this widget exactly what you saw in apps that you used before. And also because we are discussing many things simultaneously. Please look from another side: from features that you really need. And let's discuss one feature at a time.

Now: the feature that you repeated several times already:

As I've got you, you want tasks to be sorted by their due date ?! As I wrote you already, also more than once: no problem, just don't set Start date! Did you test this? Why is that not OK for you? You never told me :-(

ekalin commented 5 years ago

Well, if there was an app that worked like I wanted (and possibly like many of its other users wanted), it's reasonable to want to replicate that, isn't it?

Concerning sorting by due date, yes, that's how I believe it should be. And yes, for my use, I use only the due date, and so they appear in proper order.

But here we can also look at other people's uses: someone might want start and end dates, and tasks sorted by due date.

But then, someone might want start and end dates, and have them sorted by start date... An option to select how to sort would solve that problem, but too many options can make the app too complicated for users, not to mention the extra work to maintain and test it. But I'm diverging from the sort topic :-)

yvolk commented 5 years ago

Ok, so you personally may have tasks sorted the way you want them (just don't set Start dates). And current implementation will sort by Start Date for those users, who care about the Start Dates: they will need to set them - and voila! No changes in settings are needed for these two behaviours. This is why I think that this implementation of tasks sorting is good enough for the first release.

ekalin commented 5 years ago

Sure, but that was never a huge concern for me.

What is a concern that does limit the usability is what I described in https://github.com/plusonelabs/calendar-widget/issues/308#issuecomment-513505213. Essentially there was some code that set the task to be displayed under "Today" if it was past due. If there were several tasks that were due on several past days, they were all displayed together.

Maybe there should be some special treatment for past due tasks, but the way they're displayed in the screenshot is bad: uses a lot of space with unnecessary information and distracts from the actually useful info (one can't even see "Today"). [BTW, I like the day headers, I'm not disabling them.]

yvolk commented 5 years ago

Ok, so we're switching to another issue: day headers that are useful for a User (e.g. for you) are inconvenient/unneeded for tasks that are in the past. I already replied to you on the issue,but you didn't react on that. So:

This issue should be discussed with consideration of past Calendar events also. Your suggestion to group all past tasks under "Today" header will lead to the ugly and confusing layout, when past Calendar events are shown with their past day headers; and below them, under "Today" header, all past tasks are grouped (followed by today's calendar events), and below them calendar events and tasks start to be sorted and shown under their day headers in the unified way.

Is this the implementation that you are defending?

I personally solve your problem by using "All in one line" layout with day headers turned off.

ekalin commented 5 years ago

Well, I don't show past events: to me that completely unnecessary. I'm not sure how one should deal with past due tasks when past events are shown: perhaps in this case the tasks should also be displayed on their individual days, but "Show past events" only goes back one day, but if there's a task that's overdue by 30 days, it should be displayed (if only to remind the user to reschedule it :-) )

But without past events, as I said, I'd group all overdue tasks together. Maybe they could be in a separate "Past due" header, but even that to me is unnecessary: I'd be fine with them appearing under "Today".

I personally solve your problem by using "All in one line" layout with day headers turned off.

To me that's the ugliest layout configuration, by far :-)

yvolk commented 5 years ago

Aha, so you didn't notice yet that we have the option: "Show all past events having default color", which allows to see past events of any past date, not yesterday's only. And you agree that in the scenario that I described (past Calendar events are shown with their past day headers) grouping past tasks under today's header isn't good.

ekalin commented 5 years ago

That's even worse. I tried that option and got events starting at 1970. OK, they're recurring events (birthdays), but even not considering those, there were still real events from over a year ago. Not exactly useful for me.

yvolk commented 5 years ago

We are talking about a feature that will be in effect for all users, not for two of us. This is why we cannot ignore combinations of settings and data different from ours, telling that they are "not exactly useful" for us :-) I hope that you understand now.

yvolk commented 5 years ago

After merge of #313 this is left to be done:

yvolk commented 5 years ago

@ekalin After merging of "Event Sources" (Calendars and Tasks lists) into one list internally it came to me that having separate lists for Calendars and for Tasks lists in Settings is artificial and only complicates development and usage. So I would better keep them all for selection in one list. Just need to make clear a provider (application/API) of each source. Anyway, most of (actually all for now) other settings are the same for these two groups of events. This way after introduction of Tasks users will just see additional sources for selection in the same Settings section. ?!

ekalin commented 5 years ago

As I have been saying in my other comments (but perhaps not so explicitly), I don't think tasks are just a slightly different kind of calendar event. There are similarities, for sure, but they are different enough that treating them differently seems justified.

So, once more, I wouldn't do that.

yvolk commented 5 years ago

@ekalin Thank you, you see more differences than similarities yet you think that putting them on one widget is OK :-)

Thinking once again, and considering that:

I think that having single list to select event sources is quite logical.

yvolk commented 5 years ago

Actually, I think that "My Calendar" events are more like "My Tasks" than like "National holidays" Calendar events :-)

yvolk commented 5 years ago

@ekalin Regarding support of Tasks from Samsung Calendar. As I see in some places, Samsung is removing this feature in this year's updates, see e.g. https://eu.community.samsung.com/t5/Galaxy-S9-S9/New-Update-Calendar-Issues/td-p/940866 and https://www.reddit.com/r/GalaxyS9/comments/9xjmt0/tasks_are_missing_in_the_default_samsung_calendar/ :-(

ekalin commented 5 years ago

Well, that sucks. It's quite convenient because I already have the Samsung Calendar pre-installed, and especially because the tasks are synced (along with contacts and calendar) from my server.

There does seem to be a "Reminders" app that kind of replaces Tasks (not well, judging by the comments...)

My Samsung Calendar claims to be updated, and I still see tasks. Might be a country/locale/phone model difference, Samsung is a mess. But I can only create tasks in the synced account, not in the local task list. Could be related.

yvolk commented 5 years ago

"Header for past/due events" looks good: past-and-due-with-tasks

yvolk commented 5 years ago

Please test Beta release v.2.1.0-453: https://play.google.com/apps/testing/org.andstatus.todoagenda Or it may be downloaded from here: TodoAgenda-2.1.0-453-release.zip

ekalin commented 5 years ago

One thing you might add is a receiver for PROVIDER_CHANGED for Dmfs OpenTasks (see https://github.com/ekalin/calendar-widget/commit/48c59268a10b78a0db596a82f29a30c117e4bc29).

This won't actually work on Oreo and later because OpenTasks sends the broadcast only to its own package (https://github.com/dmfs/opentasks/blob/e711e6ea630162be184f5a0e77ac115145a291a3/opentasks-provider/src/main/java/org/dmfs/provider/tasks/TaskProvider.java#L1322), but here Android fragmentation is probably useful; I suppose there's a lot of pre-Oreo devices still around :-) Moreover, there's a note in their source code that they might be looking for a solution, so this might start working in a newer version.

yvolk commented 5 years ago

One thing you might add is a receiver for PROVIDER_CHANGED for Dmfs OpenTasks (see ekalin@48c5926).

We need to test if sending notification to the "ToDo Agenda"'s package works in Android 8+ (it should...) and if so suggest a change to the OpenTasks app?!

ekalin commented 5 years ago

I wrote a test app that sends a broadcast just like OpenTasks does (but without setPackage), and it was received by ToDo Agenda normally.

I've opened an issue with OpenTasks: https://github.com/dmfs/opentasks/issues/822

yvolk commented 5 years ago

I added "Register for notifications on Open Tasks provider changes" and did many internal fixes that should make User experience smoother. See the updated Beta package: TodoAgenda-2.1.1-460-release.zip