diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/defs.h | 1 | ||||
-rw-r--r-- | src/gmrequest.c | 12 | ||||
-rw-r--r-- | src/gmrequest.h | 2 | ||||
-rw-r--r-- | src/ui/mobile.c | 12 | ||||
-rw-r--r-- | src/ui/mobile.h | 2 | ||||
-rw-r--r-- | src/ui/uploadwidget.c | 94 |
6 files changed, 114 insertions, 9 deletions
@@ -112,6 +112,7 @@ iLocalDef int acceptKeyMod_ReturnKeyBehavior(int behavior) { | |||
112 | #define star_Icon "\u2605" | 112 | #define star_Icon "\u2605" |
113 | #define whiteStar_Icon "\u2606" | 113 | #define whiteStar_Icon "\u2606" |
114 | #define person_Icon "\U0001f464" | 114 | #define person_Icon "\U0001f464" |
115 | #define key_Icon "\U0001f511" | ||
115 | #define download_Icon "\u2ba7" | 116 | #define download_Icon "\u2ba7" |
116 | #define upload_Icon "\u2ba5" | 117 | #define upload_Icon "\u2ba5" |
117 | #define export_Icon "\U0001f4e4" | 118 | #define export_Icon "\U0001f4e4" |
diff --git a/src/gmrequest.c b/src/gmrequest.c index 00a02983..1a9e83a9 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -158,6 +158,7 @@ struct Impl_GmRequest { | |||
158 | uint32_t id; | 158 | uint32_t id; |
159 | iMutex * mtx; | 159 | iMutex * mtx; |
160 | iGmCerts * certs; /* not owned */ | 160 | iGmCerts * certs; /* not owned */ |
161 | const iGmIdentity * identity; | ||
161 | enum iGmRequestState state; | 162 | enum iGmRequestState state; |
162 | iString url; | 163 | iString url; |
163 | iTitanData * titan; | 164 | iTitanData * titan; |
@@ -527,6 +528,7 @@ static void beginGopherConnection_GmRequest_(iGmRequest *d, const iString *host, | |||
527 | void init_GmRequest(iGmRequest *d, iGmCerts *certs) { | 528 | void init_GmRequest(iGmRequest *d, iGmCerts *certs) { |
528 | d->mtx = new_Mutex(); | 529 | d->mtx = new_Mutex(); |
529 | d->id = add_Atomic(&idGen_, 1) + 1; | 530 | d->id = add_Atomic(&idGen_, 1) + 1; |
531 | d->identity = NULL; | ||
530 | d->resp = new_GmResponse(); | 532 | d->resp = new_GmResponse(); |
531 | d->isFilterEnabled = iTrue; | 533 | d->isFilterEnabled = iTrue; |
532 | d->isRespLocked = iFalse; | 534 | d->isRespLocked = iFalse; |
@@ -582,6 +584,11 @@ void setUrl_GmRequest(iGmRequest *d, const iString *url) { | |||
582 | the web. */ | 584 | the web. */ |
583 | urlEncodePath_String(&d->url); | 585 | urlEncodePath_String(&d->url); |
584 | urlEncodeSpaces_String(&d->url); | 586 | urlEncodeSpaces_String(&d->url); |
587 | d->identity = identityForUrl_GmCerts(d->certs, &d->url); | ||
588 | } | ||
589 | |||
590 | void setIdentity_GmRequest(iGmRequest *d, const iGmIdentity *id) { | ||
591 | d->identity = id; | ||
585 | } | 592 | } |
586 | 593 | ||
587 | static iBool isTitan_GmRequest_(const iGmRequest *d) { | 594 | static iBool isTitan_GmRequest_(const iGmRequest *d) { |
@@ -902,9 +909,8 @@ void submit_GmRequest(iGmRequest *d) { | |||
902 | } | 909 | } |
903 | d->state = receivingHeader_GmRequestState; | 910 | d->state = receivingHeader_GmRequestState; |
904 | d->req = new_TlsRequest(); | 911 | d->req = new_TlsRequest(); |
905 | const iGmIdentity *identity = identityForUrl_GmCerts(d->certs, &d->url); | 912 | if (d->identity) { |
906 | if (identity) { | 913 | setCertificate_TlsRequest(d->req, d->identity->cert); |
907 | setCertificate_TlsRequest(d->req, identity->cert); | ||
908 | } | 914 | } |
909 | iConnect(TlsRequest, d->req, readyRead, d, readIncoming_GmRequest_); | 915 | iConnect(TlsRequest, d->req, readyRead, d, readIncoming_GmRequest_); |
910 | iConnect(TlsRequest, d->req, sent, d, bytesSent_GmRequest_); | 916 | iConnect(TlsRequest, d->req, sent, d, bytesSent_GmRequest_); |
diff --git a/src/gmrequest.h b/src/gmrequest.h index 97b23f3c..a377ac91 100644 --- a/src/gmrequest.h +++ b/src/gmrequest.h | |||
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
28 | #include "gmutil.h" | 28 | #include "gmutil.h" |
29 | 29 | ||
30 | iDeclareType(GmCerts) | 30 | iDeclareType(GmCerts) |
31 | iDeclareType(GmIdentity) | ||
31 | iDeclareType(GmResponse) | 32 | iDeclareType(GmResponse) |
32 | 33 | ||
33 | enum iGmCertFlag { | 34 | enum iGmCertFlag { |
@@ -69,6 +70,7 @@ typedef void (*iGmRequestProgressFunc)(iGmRequest *, size_t current, size_t tota | |||
69 | 70 | ||
70 | void enableFilters_GmRequest (iGmRequest *, iBool enable); | 71 | void enableFilters_GmRequest (iGmRequest *, iBool enable); |
71 | void setUrl_GmRequest (iGmRequest *, const iString *url); | 72 | void setUrl_GmRequest (iGmRequest *, const iString *url); |
73 | void setIdentity_GmRequest (iGmRequest *, const iGmIdentity *id); | ||
72 | void setTitanData_GmRequest (iGmRequest *, const iString *mime, | 74 | void setTitanData_GmRequest (iGmRequest *, const iString *mime, |
73 | const iBlock *payload, const iString *token); | 75 | const iBlock *payload, const iString *token); |
74 | void setSendProgressFunc_GmRequest(iGmRequest *, iGmRequestProgressFunc func); | 76 | void setSendProgressFunc_GmRequest(iGmRequest *, iGmRequestProgressFunc func); |
diff --git a/src/ui/mobile.c b/src/ui/mobile.c index 459e9ce7..05e88815 100644 --- a/src/ui/mobile.c +++ b/src/ui/mobile.c | |||
@@ -156,6 +156,18 @@ static iBool mainDetailSplitHandler_(iWidget *mainDetailSplit, const char *cmd) | |||
156 | return iFalse; | 156 | return iFalse; |
157 | } | 157 | } |
158 | 158 | ||
159 | size_t currentPanelIndex_Mobile(const iWidget *panels) { | ||
160 | size_t index = 0; | ||
161 | iConstForEach(ObjectList, i, children_Widget(findChild_Widget(panels, "detailstack"))) { | ||
162 | const iWidget *child = i.object; | ||
163 | if (isVisible_Widget(child)) { | ||
164 | return index; | ||
165 | } | ||
166 | index++; | ||
167 | } | ||
168 | return iInvalidPos; | ||
169 | } | ||
170 | |||
159 | static iBool topPanelHandler_(iWidget *topPanel, const char *cmd) { | 171 | static iBool topPanelHandler_(iWidget *topPanel, const char *cmd) { |
160 | const iBool isPortrait = !isSideBySideLayout_(); | 172 | const iBool isPortrait = !isSideBySideLayout_(); |
161 | if (equal_Command(cmd, "panel.open")) { | 173 | if (equal_Command(cmd, "panel.open")) { |
diff --git a/src/ui/mobile.h b/src/ui/mobile.h index e1131953..957c0e42 100644 --- a/src/ui/mobile.h +++ b/src/ui/mobile.h | |||
@@ -39,6 +39,8 @@ void initPanels_Mobile (iWidget *panels, iWidget *parentWidget, | |||
39 | const iMenuItem *itemsNullTerminated, | 39 | const iMenuItem *itemsNullTerminated, |
40 | const iMenuItem *actions, size_t numActions); | 40 | const iMenuItem *actions, size_t numActions); |
41 | 41 | ||
42 | size_t currentPanelIndex_Mobile (const iWidget *panels); | ||
43 | |||
42 | enum iTransitionFlags { | 44 | enum iTransitionFlags { |
43 | incoming_TransitionFlag = iBit(1), | 45 | incoming_TransitionFlag = iBit(1), |
44 | dirMask_TransitionFlag = iBit(2) | iBit(3), | 46 | dirMask_TransitionFlag = iBit(2) | iBit(3), |
diff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c index c3f71ab9..34cace08 100644 --- a/src/ui/uploadwidget.c +++ b/src/ui/uploadwidget.c | |||
@@ -30,12 +30,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
30 | #include "gmrequest.h" | 30 | #include "gmrequest.h" |
31 | #include "sitespec.h" | 31 | #include "sitespec.h" |
32 | #include "window.h" | 32 | #include "window.h" |
33 | #include "gmcerts.h" | ||
33 | #include "app.h" | 34 | #include "app.h" |
34 | 35 | ||
35 | #include <the_Foundation/file.h> | 36 | #include <the_Foundation/file.h> |
36 | #include <the_Foundation/fileinfo.h> | 37 | #include <the_Foundation/fileinfo.h> |
37 | 38 | ||
38 | iDefineObjectConstruction(UploadWidget) | 39 | iDefineObjectConstruction(UploadWidget) |
40 | |||
41 | enum iUploadIdentity { | ||
42 | none_UploadIdentity, | ||
43 | defaultForUrl_UploadIdentity, | ||
44 | dropdown_UploadIdentity, | ||
45 | }; | ||
39 | 46 | ||
40 | struct Impl_UploadWidget { | 47 | struct Impl_UploadWidget { |
41 | iWidget widget; | 48 | iWidget widget; |
@@ -52,6 +59,8 @@ struct Impl_UploadWidget { | |||
52 | iLabelWidget * counter; | 59 | iLabelWidget * counter; |
53 | iString filePath; | 60 | iString filePath; |
54 | size_t fileSize; | 61 | size_t fileSize; |
62 | enum iUploadIdentity idMode; | ||
63 | iBlock idFingerprint; | ||
55 | iAtomicInt isRequestUpdated; | 64 | iAtomicInt isRequestUpdated; |
56 | }; | 65 | }; |
57 | 66 | ||
@@ -80,6 +89,26 @@ static void updateInputMaxHeight_UploadWidget_(iUploadWidget *d) { | |||
80 | (avail - inputPos.y) / lineHeight_Text(font_InputWidget(d->input)))); | 89 | (avail - inputPos.y) / lineHeight_Text(font_InputWidget(d->input)))); |
81 | } | 90 | } |
82 | 91 | ||
92 | static const iArray *makeIdentityItems_UploadWidget_(const iUploadWidget *d) { | ||
93 | iArray *items = collectNew_Array(sizeof(iMenuItem)); | ||
94 | const iGmIdentity *urlId = identityForUrl_GmCerts(certs_App(), &d->url); | ||
95 | pushBack_Array(items, &(iMenuItem){ format_CStr("${dlg.upload.id.default} (%s)", | ||
96 | urlId ? cstr_String(name_GmIdentity(urlId)) : "${dlg.upload.id.none}"), | ||
97 | 0, 0, "upload.setid arg:1" }); | ||
98 | pushBack_Array(items, &(iMenuItem){ "${dlg.upload.id.none}", 0, 0, "upload.setid arg:0" }); | ||
99 | pushBack_Array(items, &(iMenuItem){ "---" }); | ||
100 | iConstForEach(PtrArray, i, listIdentities_GmCerts(certs_App(), NULL, NULL)) { | ||
101 | const iGmIdentity *id = i.ptr; | ||
102 | pushBack_Array( | ||
103 | items, | ||
104 | &(iMenuItem){ cstr_String(name_GmIdentity(id)), 0, 0, | ||
105 | format_CStr("upload.setid fp:%s", | ||
106 | cstrCollect_String(hexEncode_Block(&id->fingerprint))) }); | ||
107 | } | ||
108 | pushBack_Array(items, &(iMenuItem){ NULL }); | ||
109 | return items; | ||
110 | } | ||
111 | |||
83 | void init_UploadWidget(iUploadWidget *d) { | 112 | void init_UploadWidget(iUploadWidget *d) { |
84 | iWidget *w = as_Widget(d); | 113 | iWidget *w = as_Widget(d); |
85 | init_Widget(w); | 114 | init_Widget(w); |
@@ -90,6 +119,8 @@ void init_UploadWidget(iUploadWidget *d) { | |||
90 | d->request = NULL; | 119 | d->request = NULL; |
91 | init_String(&d->filePath); | 120 | init_String(&d->filePath); |
92 | d->fileSize = 0; | 121 | d->fileSize = 0; |
122 | d->idMode = defaultForUrl_UploadIdentity; | ||
123 | init_Block(&d->idFingerprint, 0); | ||
93 | const iMenuItem actions[] = { | 124 | const iMenuItem actions[] = { |
94 | { "${upload.port}", 0, 0, "upload.setport" }, | 125 | { "${upload.port}", 0, 0, "upload.setport" }, |
95 | { "---" }, | 126 | { "---" }, |
@@ -117,11 +148,11 @@ void init_UploadWidget(iUploadWidget *d) { | |||
117 | initPanels_Mobile(w, NULL, (iMenuItem[]){ | 148 | initPanels_Mobile(w, NULL, (iMenuItem[]){ |
118 | { "title id:heading.upload" }, | 149 | { "title id:heading.upload" }, |
119 | { "label id:upload.info" }, | 150 | { "label id:upload.info" }, |
120 | // { "padding" }, | ||
121 | { "panel id:dlg.upload.text icon:0x1f5b9", 0, 0, (const void *) textItems }, | 151 | { "panel id:dlg.upload.text icon:0x1f5b9", 0, 0, (const void *) textItems }, |
122 | { "panel id:dlg.upload.file icon:0x1f4c1", 0, 0, (const void *) fileItems }, | 152 | { "panel id:dlg.upload.file icon:0x1f4c1", 0, 0, (const void *) fileItems }, |
123 | { "padding" }, | 153 | { "padding" }, |
124 | { "input id:upload.token hint:hint.upload.token" }, | 154 | { "dropdown id:upload.id icon:0x1f464", 0, 0, constData_Array(makeIdentityItems_UploadWidget_(d)) }, |
155 | { "input id:upload.token hint:hint.upload.token icon:0x1f511" }, | ||
125 | { NULL } | 156 | { NULL } |
126 | }, actions, iElemCount(actions)); | 157 | }, actions, iElemCount(actions)); |
127 | d->info = findChild_Widget(w, "upload.info"); | 158 | d->info = findChild_Widget(w, "upload.info"); |
@@ -205,7 +236,8 @@ void init_UploadWidget(iUploadWidget *d) { | |||
205 | updateInputMaxHeight_UploadWidget_(d); | 236 | updateInputMaxHeight_UploadWidget_(d); |
206 | } | 237 | } |
207 | 238 | ||
208 | void deinit_UploadWidget(iUploadWidget *d) { | 239 | void deinit_UploadWidget(iUploadWidget *d) { |
240 | deinit_Block(&d->idFingerprint); | ||
209 | deinit_String(&d->filePath); | 241 | deinit_String(&d->filePath); |
210 | deinit_String(&d->url); | 242 | deinit_String(&d->url); |
211 | deinit_String(&d->originalUrl); | 243 | deinit_String(&d->originalUrl); |
@@ -263,6 +295,15 @@ static void requestFinished_UploadWidget_(iUploadWidget *d, iGmRequest *req) { | |||
263 | postCommand_Widget(d, "upload.request.finished reqid:%u", id_GmRequest(req)); | 295 | postCommand_Widget(d, "upload.request.finished reqid:%u", id_GmRequest(req)); |
264 | } | 296 | } |
265 | 297 | ||
298 | static void updateIdentityDropdown_UploadWidget_(iUploadWidget *d) { | ||
299 | updateDropdownSelection_LabelWidget( | ||
300 | findChild_Widget(as_Widget(d), "upload.id"), | ||
301 | d->idMode == none_UploadIdentity ? " arg:0" | ||
302 | : d->idMode == defaultForUrl_UploadIdentity | ||
303 | ? " arg:1" | ||
304 | : format_CStr(" fp:%s", cstrCollect_String(hexEncode_Block(&d->idFingerprint)))); | ||
305 | } | ||
306 | |||
266 | static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | 307 | static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { |
267 | iWidget *w = as_Widget(d); | 308 | iWidget *w = as_Widget(d); |
268 | const char *cmd = command_UserEvent(ev); | 309 | const char *cmd = command_UserEvent(ev); |
@@ -290,9 +331,36 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
290 | } | 331 | } |
291 | return iTrue; | 332 | return iTrue; |
292 | } | 333 | } |
334 | if (isCommand_Widget(w, ev, "upload.setid")) { | ||
335 | if (hasLabel_Command(cmd, "fp")) { | ||
336 | set_Block(&d->idFingerprint, collect_Block(hexDecode_Rangecc(range_Command(cmd, "fp")))); | ||
337 | d->idMode = dropdown_UploadIdentity; | ||
338 | } | ||
339 | else if (arg_Command(cmd)) { | ||
340 | clear_Block(&d->idFingerprint); | ||
341 | d->idMode = defaultForUrl_UploadIdentity; | ||
342 | } | ||
343 | else { | ||
344 | clear_Block(&d->idFingerprint); | ||
345 | d->idMode = none_UploadIdentity; | ||
346 | } | ||
347 | updateIdentityDropdown_UploadWidget_(d); | ||
348 | return iTrue; | ||
349 | } | ||
293 | if (isCommand_Widget(w, ev, "upload.accept")) { | 350 | if (isCommand_Widget(w, ev, "upload.accept")) { |
294 | iWidget * tabs = findChild_Widget(w, "upload.tabs"); | 351 | iBool isText; |
295 | const int tabIndex = tabPageIndex_Widget(tabs, currentTabPage_Widget(tabs)); | 352 | iWidget *tabs = findChild_Widget(w, "upload.tabs"); |
353 | if (tabs) { | ||
354 | const size_t tabIndex = tabPageIndex_Widget(tabs, currentTabPage_Widget(tabs)); | ||
355 | isText = (tabIndex == 0); | ||
356 | } | ||
357 | else { | ||
358 | const size_t panelIndex = currentPanelIndex_Mobile(w); | ||
359 | if (panelIndex == iInvalidPos) { | ||
360 | return iTrue; | ||
361 | } | ||
362 | isText = (currentPanelIndex_Mobile(w) == 0); | ||
363 | } | ||
296 | /* Make a GmRequest and send the data. */ | 364 | /* Make a GmRequest and send the data. */ |
297 | iAssert(d->request == NULL); | 365 | iAssert(d->request == NULL); |
298 | iAssert(!isEmpty_String(&d->url)); | 366 | iAssert(!isEmpty_String(&d->url)); |
@@ -300,7 +368,21 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
300 | setSendProgressFunc_GmRequest(d->request, updateProgress_UploadWidget_); | 368 | setSendProgressFunc_GmRequest(d->request, updateProgress_UploadWidget_); |
301 | setUserData_Object(d->request, d); | 369 | setUserData_Object(d->request, d); |
302 | setUrl_GmRequest(d->request, &d->url); | 370 | setUrl_GmRequest(d->request, &d->url); |
303 | if (tabIndex == 0) { | 371 | switch (d->idMode) { |
372 | case defaultForUrl_UploadIdentity: | ||
373 | break; /* GmRequest handles it */ | ||
374 | case none_UploadIdentity: | ||
375 | setIdentity_GmRequest(d->request, NULL); | ||
376 | signOut_GmCerts(certs_App(), url_GmRequest(d->request)); | ||
377 | break; | ||
378 | case dropdown_UploadIdentity: { | ||
379 | iGmIdentity *ident = findIdentity_GmCerts(certs_App(), &d->idFingerprint); | ||
380 | setIdentity_GmRequest(d->request, ident); | ||
381 | signIn_GmCerts(certs_App(), ident, url_GmRequest(d->request)); | ||
382 | break; | ||
383 | } | ||
384 | } | ||
385 | if (isText) { | ||
304 | /* Uploading text. */ | 386 | /* Uploading text. */ |
305 | setTitanData_GmRequest(d->request, | 387 | setTitanData_GmRequest(d->request, |
306 | collectNewCStr_String("text/plain"), | 388 | collectNewCStr_String("text/plain"), |