diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-17 15:36:37 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-17 15:36:37 +0300 |
commit | c5463b0aec571b8d9451ddadb656a061e22e7f2f (patch) | |
tree | fdc36a94f74e9933d8d2064ebc3070c6f12530a2 /src/ui/uploadwidget.c | |
parent | 635eabab8b932ca01fc5b391cda20e23e40a6532 (diff) |
Working on Titan uploads
There may be a bug in `TlsRequest` when sending out large amounts of data.
Diffstat (limited to 'src/ui/uploadwidget.c')
-rw-r--r-- | src/ui/uploadwidget.c | 110 |
1 files changed, 106 insertions, 4 deletions
diff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c index 036571a5..968b3775 100644 --- a/src/ui/uploadwidget.c +++ b/src/ui/uploadwidget.c | |||
@@ -25,9 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
25 | #include "inputwidget.h" | 25 | #include "inputwidget.h" |
26 | #include "documentwidget.h" | 26 | #include "documentwidget.h" |
27 | #include "color.h" | 27 | #include "color.h" |
28 | #include "command.h" | ||
28 | #include "gmrequest.h" | 29 | #include "gmrequest.h" |
29 | #include "app.h" | 30 | #include "app.h" |
30 | 31 | ||
32 | #include <the_Foundation/file.h> | ||
33 | #include <the_Foundation/fileinfo.h> | ||
34 | |||
31 | iDefineObjectConstruction(UploadWidget) | 35 | iDefineObjectConstruction(UploadWidget) |
32 | 36 | ||
33 | struct Impl_UploadWidget { | 37 | struct Impl_UploadWidget { |
@@ -39,6 +43,11 @@ struct Impl_UploadWidget { | |||
39 | iInputWidget * mime; | 43 | iInputWidget * mime; |
40 | iInputWidget * token; | 44 | iInputWidget * token; |
41 | iInputWidget * input; | 45 | iInputWidget * input; |
46 | iLabelWidget * filePathLabel; | ||
47 | iLabelWidget * fileSizeLabel; | ||
48 | iString filePath; | ||
49 | size_t fileSize; | ||
50 | iAtomicInt isRequestUpdated; | ||
42 | }; | 51 | }; |
43 | 52 | ||
44 | void init_UploadWidget(iUploadWidget *d) { | 53 | void init_UploadWidget(iUploadWidget *d) { |
@@ -49,6 +58,8 @@ void init_UploadWidget(iUploadWidget *d) { | |||
49 | init_String(&d->url); | 58 | init_String(&d->url); |
50 | d->viewer = NULL; | 59 | d->viewer = NULL; |
51 | d->request = NULL; | 60 | d->request = NULL; |
61 | init_String(&d->filePath); | ||
62 | d->fileSize = 0; | ||
52 | addChildFlags_Widget(w, | 63 | addChildFlags_Widget(w, |
53 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)), | 64 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)), |
54 | frameless_WidgetFlag); | 65 | frameless_WidgetFlag); |
@@ -64,10 +75,11 @@ void init_UploadWidget(iUploadWidget *d) { | |||
64 | iWidget *page = new_Widget(); | 75 | iWidget *page = new_Widget(); |
65 | setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue); | 76 | setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue); |
66 | d->input = new_InputWidget(0); | 77 | d->input = new_InputWidget(0); |
78 | setHint_InputWidget(d->input, "${hint.upload.text}"); | ||
67 | setEnterInsertsLF_InputWidget(d->input, iTrue); | 79 | setEnterInsertsLF_InputWidget(d->input, iTrue); |
68 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); | 80 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); |
69 | addChild_Widget(page, iClob(d->input)); | 81 | addChild_Widget(page, iClob(d->input)); |
70 | appendTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); | 82 | appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); |
71 | } | 83 | } |
72 | /* File content. */ { | 84 | /* File content. */ { |
73 | appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); | 85 | appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); |
@@ -75,9 +87,9 @@ void init_UploadWidget(iUploadWidget *d) { | |||
75 | // iWidget *hint = addChild_Widget(values, iClob(new_LabelWidget("${upload.file.drophint}", NULL))); | 87 | // iWidget *hint = addChild_Widget(values, iClob(new_LabelWidget("${upload.file.drophint}", NULL))); |
76 | // pad->sizeRef = hint; | 88 | // pad->sizeRef = hint; |
77 | addChild_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL))); | 89 | addChild_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL))); |
78 | addChild_Widget(values, iClob(new_LabelWidget("filename.ext", NULL))); | 90 | d->filePathLabel = addChild_Widget(values, iClob(new_LabelWidget("${upload.file.drophere}", NULL))); |
79 | addChild_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL))); | 91 | addChild_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL))); |
80 | addChild_Widget(values, iClob(new_LabelWidget("0 KB", NULL))); | 92 | d->fileSizeLabel = addChild_Widget(values, iClob(new_LabelWidget("\u2014", NULL))); |
81 | d->mime = new_InputWidget(0); | 93 | d->mime = new_InputWidget(0); |
82 | setFixedSize_Widget(as_Widget(d->mime), init_I2(50 * gap_UI, -1)); | 94 | setFixedSize_Widget(as_Widget(d->mime), init_I2(50 * gap_UI, -1)); |
83 | addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime)); | 95 | addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime)); |
@@ -100,6 +112,10 @@ void init_UploadWidget(iUploadWidget *d) { | |||
100 | KMOD_PRIMARY, | 112 | KMOD_PRIMARY, |
101 | "upload.accept" } }, | 113 | "upload.accept" } }, |
102 | 2); | 114 | 2); |
115 | setId_Widget(addChildPosFlags_Widget(buttons, | ||
116 | iClob(new_LabelWidget("0", NULL)), | ||
117 | front_WidgetAddPos, frameless_WidgetFlag), | ||
118 | "upload.pending"); | ||
103 | addChild_Widget(w, iClob(buttons)); | 119 | addChild_Widget(w, iClob(buttons)); |
104 | } | 120 | } |
105 | resizeToLargestPage_Widget(tabs); | 121 | resizeToLargestPage_Widget(tabs); |
@@ -107,12 +123,16 @@ void init_UploadWidget(iUploadWidget *d) { | |||
107 | } | 123 | } |
108 | 124 | ||
109 | void deinit_UploadWidget(iUploadWidget *d) { | 125 | void deinit_UploadWidget(iUploadWidget *d) { |
126 | deinit_String(&d->filePath); | ||
110 | deinit_String(&d->url); | 127 | deinit_String(&d->url); |
111 | iRelease(d->request); | 128 | iRelease(d->request); |
112 | } | 129 | } |
113 | 130 | ||
114 | void setUrl_UploadWidget(iUploadWidget *d, const iString *url) { | 131 | void setUrl_UploadWidget(iUploadWidget *d, const iString *url) { |
115 | set_String(&d->url, url); | 132 | iUrl parts; |
133 | init_Url(&parts, url); | ||
134 | setCStr_String(&d->url, "titan"); | ||
135 | appendRange_String(&d->url, (iRangecc){ parts.scheme.end, constEnd_String(url) }); | ||
116 | setText_LabelWidget(d->info, &d->url); | 136 | setText_LabelWidget(d->info, &d->url); |
117 | } | 137 | } |
118 | 138 | ||
@@ -120,6 +140,20 @@ void setResponseViewer_UploadWidget(iUploadWidget *d, iDocumentWidget *doc) { | |||
120 | d->viewer = doc; | 140 | d->viewer = doc; |
121 | } | 141 | } |
122 | 142 | ||
143 | static iWidget *acceptButton_UploadWidget_(iUploadWidget *d) { | ||
144 | return lastChild_Widget(findChild_Widget(as_Widget(d), "dialogbuttons")); | ||
145 | } | ||
146 | |||
147 | static void requestUpdated_UploadWidget_(iUploadWidget *d, iGmRequest *req) { | ||
148 | if (!exchange_Atomic(&d->isRequestUpdated, iTrue)) { | ||
149 | postCommand_Widget(d, "upload.request.updated reqid:%u", id_GmRequest(req)); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | static void requestFinished_UploadWidget_(iUploadWidget *d, iGmRequest *req) { | ||
154 | postCommand_Widget(d, "upload.request.finished reqid:%u", id_GmRequest(req)); | ||
155 | } | ||
156 | |||
123 | static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | 157 | static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { |
124 | iWidget *w = as_Widget(d); | 158 | iWidget *w = as_Widget(d); |
125 | if (isCommand_Widget(w, ev, "upload.cancel")) { | 159 | if (isCommand_Widget(w, ev, "upload.cancel")) { |
@@ -128,12 +162,80 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
128 | destroy_Widget(w); | 162 | destroy_Widget(w); |
129 | return iTrue; | 163 | return iTrue; |
130 | } | 164 | } |
165 | const char *cmd = command_UserEvent(ev); | ||
131 | if (isCommand_Widget(w, ev, "upload.accept")) { | 166 | if (isCommand_Widget(w, ev, "upload.accept")) { |
167 | iWidget * tabs = findChild_Widget(w, "upload.tabs"); | ||
168 | const int tabIndex = tabPageIndex_Widget(tabs, currentTabPage_Widget(tabs)); | ||
132 | /* Make a GmRequest and send the data. */ | 169 | /* Make a GmRequest and send the data. */ |
170 | iAssert(d->request == NULL); | ||
171 | iAssert(!isEmpty_String(&d->url)); | ||
172 | d->request = new_GmRequest(certs_App()); | ||
173 | setUrl_GmRequest(d->request, &d->url); | ||
174 | if (tabIndex == 0) { | ||
175 | /* Uploading text. */ | ||
176 | setTitanData_GmRequest(d->request, | ||
177 | collectNewCStr_String("text/plain"), | ||
178 | utf8_String(text_InputWidget(d->input)), | ||
179 | text_InputWidget(d->token)); | ||
180 | } | ||
181 | else { | ||
182 | /* Uploading a file. */ | ||
183 | iFile *f = iClob(new_File(&d->filePath)); | ||
184 | if (!open_File(f, readOnly_FileMode)) { | ||
185 | makeMessage_Widget("${heading.upload.error.file}", | ||
186 | "${upload.error.msg}", | ||
187 | (iMenuItem[]){ "${dlg.message.ok}", 0, 0, "message.ok" }, 1); | ||
188 | iReleasePtr(&d->request); | ||
189 | return iTrue; | ||
190 | } | ||
191 | setTitanData_GmRequest(d->request, | ||
192 | text_InputWidget(d->mime), | ||
193 | collect_Block(readAll_File(f)), | ||
194 | text_InputWidget(d->token)); | ||
195 | close_File(f); | ||
196 | } | ||
197 | iConnect(GmRequest, d->request, updated, d, requestUpdated_UploadWidget_); | ||
198 | iConnect(GmRequest, d->request, finished, d, requestFinished_UploadWidget_); | ||
199 | submit_GmRequest(d->request); | ||
133 | /* The dialog will remain open until the request finishes, showing upload progress. */ | 200 | /* The dialog will remain open until the request finishes, showing upload progress. */ |
201 | setFocus_Widget(NULL); | ||
202 | setFlags_Widget(tabs, disabled_WidgetFlag, iTrue); | ||
203 | setFlags_Widget(as_Widget(d->token), disabled_WidgetFlag, iTrue); | ||
204 | setFlags_Widget(acceptButton_UploadWidget_(d), disabled_WidgetFlag, iTrue); | ||
205 | return iTrue; | ||
206 | } | ||
207 | else if (isCommand_Widget(w, ev, "upload.request.updated")) { | ||
208 | /* TODO: Upload progress update? */ | ||
209 | } | ||
210 | else if (isCommand_Widget(w, ev, "upload.request.finished") && | ||
211 | id_GmRequest(d->request) == argU32Label_Command(cmd, "reqid")) { | ||
212 | if (d->viewer) { | ||
213 | takeRequest_DocumentWidget(d->viewer, d->request); | ||
214 | d->request = NULL; /* DocumentWidget has it now. */ | ||
215 | } | ||
216 | setupSheetTransition_Mobile(w, iFalse); | ||
217 | destroy_Widget(w); | ||
218 | return iTrue; | ||
134 | } | 219 | } |
135 | if (ev->type == SDL_DROPFILE) { | 220 | if (ev->type == SDL_DROPFILE) { |
136 | /* Switch to File tab. */ | 221 | /* Switch to File tab. */ |
222 | iWidget *tabs = findChild_Widget(w, "upload.tabs"); | ||
223 | showTabPage_Widget(tabs, tabPage_Widget(tabs, 1)); | ||
224 | setCStr_String(&d->filePath, ev->drop.file); | ||
225 | iFileInfo *info = iClob(new_FileInfo(&d->filePath)); | ||
226 | if (isDirectory_FileInfo(info)) { | ||
227 | makeMessage_Widget("${heading.upload.error.file}", | ||
228 | "${upload.error.directory}", | ||
229 | (iMenuItem[]){ "${dlg.message.ok}", 0, 0, "message.ok" }, 1); | ||
230 | clear_String(&d->filePath); | ||
231 | d->fileSize = 0; | ||
232 | return iTrue; | ||
233 | } | ||
234 | d->fileSize = size_FileInfo(info); | ||
235 | setText_LabelWidget(d->filePathLabel, &d->filePath); | ||
236 | setTextCStr_LabelWidget(d->fileSizeLabel, formatCStrs_Lang("num.bytes.n", d->fileSize)); | ||
237 | setTextCStr_InputWidget(d->mime, mediaType_Path(&d->filePath)); | ||
238 | return iTrue; | ||
137 | } | 239 | } |
138 | return processEvent_Widget(w, ev); | 240 | return processEvent_Widget(w, ev); |
139 | } | 241 | } |