Skip to content

Commit

Permalink
feat: improve caldav
Browse files Browse the repository at this point in the history
  • Loading branch information
alainm23 committed Jan 25, 2024
1 parent 82fb9ae commit ec2972e
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 64 deletions.
13 changes: 6 additions & 7 deletions core/Objects/Item.vala
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,15 @@ public class Objects.Item : Objects.BaseObject {
due.date = Util.ical_to_date_time_local (ical.get_due ()).to_string ();
}

string _parent_id = Util.find_string_value ("RELATED-TO", data);
if (_parent_id != "") {
parent_id = _parent_id;
}
parent_id = Util.find_string_value ("RELATED-TO", data);

if (ical.get_status () == ICal.PropertyStatus.COMPLETED) {
checked = true;
var completed_datetime = ical.get_first_property (ICal.PropertyKind.COMPLETED_PROPERTY);
if (completed_datetime != null) {
completed_at = Util.ical_to_date_time_local (completed_datetime.get_completed ()).to_string ();
string completed = Util.find_string_value ("COMPLETED", data);
if (completed != "") {
completed_at = Util.get_default ().get_format_date (
Util.ical_to_date_time_local (new ICal.Time.from_string (completed))
).to_string ();
} else {
completed_at = Util.get_default ().get_format_date (new GLib.DateTime.now_local ()).to_string ();
}
Expand Down
56 changes: 48 additions & 8 deletions core/Services/CalDAV.vala
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public class Services.CalDAV : GLib.Object {
GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ());
GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response");
foreach (GXml.DomElement element in response) {
if (is_calendar (element)) {
if (is_vtodo_calendar (element)) {
var project = new Objects.Project.from_caldav_xml (element);
Services.Database.get_default ().insert_project (project);
yield get_all_tasks_by_tasklist (project);
Expand Down Expand Up @@ -394,15 +394,19 @@ public class Services.CalDAV : GLib.Object {

if (item != null) {
string old_project_id = item.project_id;
string old_section_id = item.section_id;
string old_parent_id = item.parent_id;

item.update_from_caldav_xml (element);
item.project_id = project.id;
Services.Database.get_default ().update_item (item);

// TODO: Fix moved
if (old_parent_id != item.parent_id) {
Services.EventBus.get_default ().item_moved (item, old_project_id, old_section_id, old_parent_id);
if (old_project_id != item.project_id || old_parent_id != item.parent_id) {
print ("old_project_id: %s\n".printf (old_project_id));
print ("old_parent_id: %s\n".printf (old_parent_id));
print ("project_id: %s\n".printf (item.project_id));
print ("parent_id: %s\n".printf (item.parent_id));

Services.EventBus.get_default ().item_moved (item, old_project_id, "", old_parent_id);
}

bool old_checked = item.checked;
Expand Down Expand Up @@ -462,7 +466,7 @@ public class Services.CalDAV : GLib.Object {
GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ());
GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response");
foreach (GXml.DomElement element in response) {
if (is_calendar (element)) {
if (is_vtodo_calendar (element)) {
Objects.Project? project = Services.Database.get_default ().get_project (get_id_from_url (element));
if (project == null) {
project = new Objects.Project.from_caldav_xml (element);
Expand Down Expand Up @@ -652,6 +656,33 @@ public class Services.CalDAV : GLib.Object {
return response;
}

public async HttpResponse move_task (Objects.Item item, string project_id) {
var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url");
var username = Services.Settings.get_default ().settings.get_string ("caldav-username");
var credential = Services.Settings.get_default ().settings.get_string ("caldav-credential");

var url = "%s/remote.php/dav/calendars/%s/%s/%s".printf (server_url, username, item.project.id, item.ics);
var destination = "/remote.php/dav/calendars/%s/%s/%s".printf (username, project_id, item.ics);

var message = new Soup.Message ("MOVE", url);
message.request_headers.append ("Authorization", "Basic %s".printf (credential));
message.request_headers.append ("Destination", destination);

HttpResponse response = new HttpResponse ();

try {
yield session.send_and_read_async (message, GLib.Priority.HIGH, null);

if (message.status_code == 201) {
response.status = true;
}
} catch (Error e) {
debug (e.message);
}

return response;
}

public void remove_items () {
Services.Settings.get_default ().settings.set_string ("caldav-server-url", "");
Services.Settings.get_default ().settings.set_string ("caldav-username", "");
Expand Down Expand Up @@ -699,11 +730,20 @@ public class Services.CalDAV : GLib.Object {
return server_url != "" && username != "" && credential != "";
}

public bool is_calendar (GXml.DomElement element) {
public bool is_vtodo_calendar (GXml.DomElement element) {
GXml.DomElement propstat = element.get_elements_by_tag_name ("d:propstat").get_element (0);
GXml.DomElement prop = propstat.get_elements_by_tag_name ("d:prop").get_element (0);
GXml.DomElement resourcetype = prop.get_elements_by_tag_name ("d:resourcetype").get_element (0);
return resourcetype.get_elements_by_tag_name ("cal:calendar").length > 0;

bool is_calendar = resourcetype.get_elements_by_tag_name ("cal:calendar").length > 0;
bool is_vtodo = false;
if (is_calendar) {
GXml.DomElement supported_calendar = prop.get_elements_by_tag_name ("cal:supported-calendar-component-set").get_element (0);
GXml.DomElement calendar_comp = supported_calendar.get_elements_by_tag_name ("cal:comp").get_element (0);
is_vtodo = calendar_comp.get_attribute ("name") == "VTODO";
}

return is_vtodo;
}

public bool is_deleted_calendar (GXml.DomElement element) {
Expand Down
18 changes: 16 additions & 2 deletions core/Widgets/ProjectPicker/ProjectPickerButton.vala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class Widgets.ProjectPicker.ProjectPickerButton : Adw.Bin {
private Gtk.Label section_label;
private Layouts.HeaderItem sections_group;
private Gtk.Popover sections_popover;
private Gtk.Revealer section_box_revealer;

public signal void project_change (Objects.Project project);
public signal void section_change (Objects.Section? section);
Expand Down Expand Up @@ -61,16 +62,28 @@ public class Widgets.ProjectPicker.ProjectPickerButton : Adw.Bin {
};

sections_popover = build_sections_popover ();

var arrow_label = new Gtk.Label ("");

var section_button = new Gtk.MenuButton () {
popover = sections_popover,
child = section_label,
css_classes = { Granite.STYLE_CLASS_FLAT }
};

var section_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
section_box.append (arrow_label);
section_box.append (section_button);

section_box_revealer = new Gtk.Revealer () {
transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT,
reveal_child = true,
child = section_box
};

var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
box.append (project_button);
box.append (new Gtk.Label (""));
box.append (section_button);
box.append (section_box_revealer);

child = box;

Expand All @@ -86,6 +99,7 @@ public class Widgets.ProjectPicker.ProjectPickerButton : Adw.Bin {
name_label.label = project.is_inbox_project ? _("Inbox") : project.name;
icon_project.project = project;
icon_project.update_request ();
section_box_revealer.reveal_child = project.backend_type != BackendType.CALDAV;
}

private Gtk.Popover build_sections_popover () {
Expand Down
8 changes: 8 additions & 0 deletions core/Widgets/ProjectPicker/ProjectPickerPopover.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,16 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover {
};
todoist_group.show_action = false;

var nextcloud_group = new Layouts.HeaderItem (_("Nextcloud")) {
reveal_child = Services.Database.get_default ().get_projects_by_backend_type (BackendType.CALDAV).size > 0
};
nextcloud_group.show_action = false;

var scrolled_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
scrolled_box.append (inbox_group);
scrolled_box.append (local_group);
scrolled_box.append (todoist_group);
scrolled_box.append (nextcloud_group);

var listbox = new Gtk.ListBox () {
hexpand = true,
Expand Down Expand Up @@ -92,6 +98,8 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover {
local_group.add_child (row);
} else if (project.backend_type == BackendType.TODOIST) {
todoist_group.add_child (row);
} else if (project.backend_type == BackendType.CALDAV) {
nextcloud_group.add_child (row);
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/Dialogs/Preferences/PreferencesWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1293,15 +1293,12 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesWindow {
var settings_header = new Dialogs.Preferences.SettingsHeader (_("CalDAV Setup"));

var username_entry = new Adw.EntryRow ();
username_entry.text = "[email protected]";
username_entry.title = _("User Name");

var password_entry = new Adw.PasswordEntryRow ();
password_entry.text = "Estrater@200";
password_entry.title = _("Password");

var server_entry = new Adw.EntryRow ();
server_entry.text = "https://evi.nl.tab.digital/";
server_entry.title = _("Server URL");

var providers_model = new Gtk.StringList (null);
Expand Down
23 changes: 19 additions & 4 deletions src/Dialogs/ProjectPicker/ProjectPicker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Window {
private Layouts.HeaderItem inbox_group;
private Layouts.HeaderItem local_group;
private Layouts.HeaderItem todoist_group;
private Layouts.HeaderItem caldav_group;

public Gee.HashMap <string, Dialogs.ProjectPicker.ProjectPickerRow> projects_hashmap;

Expand Down Expand Up @@ -126,6 +127,7 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Window {
search_entry.search_changed.connect (() => {
local_group.invalidate_filter ();
todoist_group.invalidate_filter ();
caldav_group.invalidate_filter ();
});

Services.EventBus.get_default ().project_picker_changed.connect ((id) => {
Expand Down Expand Up @@ -164,10 +166,14 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Window {
todoist_group = new Layouts.HeaderItem (_("Todoist"));
todoist_group.show_action = false;

caldav_group = new Layouts.HeaderItem (_("Nextcloud"));
caldav_group.show_action = false;

if (backend_type == BackendType.ALL) {
inbox_group.reveal = true;
local_group.reveal = true;
todoist_group.reveal = true;
caldav_group.reveal = true;
} else if (backend_type == BackendType.LOCAL) {
inbox_group.reveal = Services.Settings.get_default ().settings.get_enum ("default-inbox") == 0;
local_group.reveal = true;
Expand All @@ -176,10 +182,16 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Window {
inbox_group.reveal = Services.Settings.get_default ().settings.get_enum ("default-inbox") == 1;
local_group.reveal = false;
todoist_group.reveal = true;
} else if (backend_type == BackendType.CALDAV) {
inbox_group.reveal = false;
local_group.reveal = false;
todoist_group.reveal = false;
caldav_group.reveal = true;
}

local_group.set_filter_func (filter_func);
todoist_group.set_filter_func (filter_func);
caldav_group.set_filter_func (filter_func);

var scrolled_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) {
margin_start = 12,
Expand All @@ -188,6 +200,7 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Window {
scrolled_box.append (inbox_group);
scrolled_box.append (local_group);
scrolled_box.append (todoist_group);
scrolled_box.append (caldav_group);

var scrolled = new Gtk.ScrolledWindow () {
hexpand = true,
Expand Down Expand Up @@ -234,15 +247,17 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Window {

private void add_projects () {
foreach (Objects.Project project in Services.Database.get_default ().projects) {
projects_hashmap [project.id_string] = new Dialogs.ProjectPicker.ProjectPickerRow (project);
projects_hashmap [project.id] = new Dialogs.ProjectPicker.ProjectPickerRow (project);

if (project.is_inbox_project) {
inbox_group.add_child (projects_hashmap [project.id_string]);
inbox_group.add_child (projects_hashmap [project.id]);
} else {
if (project.backend_type == BackendType.LOCAL) {
local_group.add_child (projects_hashmap [project.id_string]);
local_group.add_child (projects_hashmap [project.id]);
} else if (project.backend_type == BackendType.TODOIST) {
todoist_group.add_child (projects_hashmap [project.id_string]);
todoist_group.add_child (projects_hashmap [project.id]);
} else if (project.backend_type == BackendType.CALDAV) {
caldav_group.add_child (projects_hashmap [project.id]);
}
}
}
Expand Down
19 changes: 15 additions & 4 deletions src/Layouts/ItemRow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,9 @@ public class Layouts.ItemRow : Layouts.ItemBase {
}

if (item.project_id != project_id || item.section_id != section_id) {
if (item.project.backend_type == BackendType.TODOIST) {
if (item.project.backend_type == BackendType.LOCAL) {
move_item (project_id, section_id);
} else if (item.project.backend_type == BackendType.TODOIST) {
is_loading = true;

string move_id = project_id;
Expand All @@ -1376,11 +1378,20 @@ public class Layouts.ItemRow : Layouts.ItemBase {
move_item (project_id, section_id);
is_loading = false;
} else {
main_revealer.reveal_child = true;
is_loading = false;
}
});
} else if (item.project.backend_type == BackendType.CALDAV) {
is_loading = true;

Services.CalDAV.get_default ().move_task.begin (item, project_id, (obj, res) => {
if (Services.CalDAV.get_default ().move_task.end (res).status) {
move_item (project_id, section_id);
is_loading = false;
} else {
is_loading = false;
}
});
} else if (item.project.backend_type == BackendType.LOCAL) {
move_item (project_id, section_id);
}
}
}
Expand Down
Loading

0 comments on commit ec2972e

Please sign in to comment.