aboutsummaryrefslogtreecommitdiff
path: root/static/ts/server_connect.ts
blob: ad4bc9eb687a579795eacdc6771eae3cc446ca71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
 * Procedures for interfacing with the backend server.
 *
 * @module
 */

export { create_event, remove_event }

import { jcal_to_xcal } from './jcal'
import { VEvent } from './vevent'
import { uid } from './types'
import { vcal_objects } from './globals'
import { PopupElement } from './components/popup-element'

/**
 * Requests that the server permanently remove the event with the given
 * unique id from its persistant storage.
 *
 * If the server responds with a success also delete it from our local
 * store (`vcal_objects`).
 *
 * // TODO link to our backend flow here
*/
async function remove_event(uid: uid) {
    let element = vcal_objects.get(uid);
    if (!element) {
        console.error(`No VEvent with that uid = '${uid}', giving up`)
        return;
    }

    let data = new URLSearchParams();
    data.append('uid', uid);

    let response = await fetch('/remove', {
        method: 'POST',
        body: data
    });

    console.log(response);
    // toggle_popup(popup_from_event(element));

    if (response.status < 200 || response.status >= 300) {
        let body = await response.text();
        alert(`HTTP error ${response.status}\n${body}`)
    } else {
        /* Remove all HTML components which belong to this vevent */
        for (let component of element.registered) {
            component.remove();
        }
        /* remove the vevent from our global store,
           hopefully also freeing it for garbace collection */
        vcal_objects.delete(uid);
    }
}

// function event_to_jcal(event) {
//     /* encapsulate event in a shim calendar, to ensure that
//        we always send correct stuff */
//     return ['vcalendar',
//         [
//             /*
//               'prodid' and 'version' are technically both required (RFC 5545,
//               3.6 Calendar Components).
//             */
//         ],
//         [
//             /* vtimezone goes here */
//             event.properties.to_jcal()
//         ]
//     ];
// }

/**
 * Packs up the given event and sends it to the server to either be
 * created, or simply be updated in the persistant database.

 * Also does some minor updates registered components, to show that the
 * event is actually created.
*/
async function create_event(event: VEvent) {

    // let xml = event.getElementsByTagName("icalendar")[0].outerHTML
    let calendar = event.calendar;
    if (!calendar) {
        console.error("Can't create event without calendar")
        return;
    }

    console.log('calendar =', atob(calendar)/*, xml*/);

    let data = new URLSearchParams();
    data.append("cal", calendar);
    // data.append("data", xml);

    // console.log(event);

    let jcal = event.to_jcal();
    // console.log(jcal);

    let doc: Document = jcal_to_xcal(jcal);
    // console.log(doc);
    let str = doc.documentElement.outerHTML;
    console.log(str);
    data.append("data", str);

    // console.log(event.properties);

    let response = await fetch('/insert', {
        method: 'POST',
        body: data
    });

    console.log(response);
    if (response.status < 200 || response.status >= 300) {
        let body = await response.text();
        alert(`HTTP error ${response.status}\n${body}`)
        return;
    }

    /* response from here on is good */

    // let body = await response.text();

    /* server is assumed to return an XML document on the form
       <properties>
       **xcal property** ...
       </properties>
       parse that, and update our own vevent with the data.
    */

    // let parser = new DOMParser();
    // let return_properties = parser
    //     .parseFromString(body, 'text/xml')
    //     .children[0];

    // let child;
    // while ((child = return_properties.firstChild)) {
    //     let target = event.querySelector(
    //         "vevent properties " + child.tagName);
    //     if (target) {
    //         target.replaceWith(child);
    //     } else {
    //         event.querySelector("vevent properties")
    //             .appendChild(child);
    //     }
    // }

    for (let r of event.registered) {
        r.classList.remove('generated');
        if (r instanceof PopupElement) {
            console.log(r);
            r.removeAttribute('visible');
        }
    }
}