summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-10-18 08:15:08 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-10-18 08:15:08 +0300
commit3fb04c28f22475814708f69022eae5220d542108 (patch)
tree92d8827f9666a38fcb0d90127a6d978512ec5b77 /src/ui/documentwidget.c
parent917b425c7ed9dbcc6a029260af0b820dd132e35c (diff)
DocumentWidget: Unsupported content downloads
Don't try to show a document while a long download is progressing, especially if we don't have any way to present the document format.
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c78
1 files changed, 53 insertions, 25 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index a1992967..cf2dc5da 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -228,6 +228,7 @@ enum iDocumentWidgetFlag {
228 otherRootByDefault_DocumentWidgetFlag = iBit(12), /* links open to other root by default */ 228 otherRootByDefault_DocumentWidgetFlag = iBit(12), /* links open to other root by default */
229 urlChanged_DocumentWidgetFlag = iBit(13), 229 urlChanged_DocumentWidgetFlag = iBit(13),
230 openedFromSidebar_DocumentWidgetFlag = iBit(14), 230 openedFromSidebar_DocumentWidgetFlag = iBit(14),
231 drawDownloadCounter_DocumentWidgetFlag = iBit(15),
231}; 232};
232 233
233enum iDocumentLinkOrdinalMode { 234enum iDocumentLinkOrdinalMode {
@@ -275,7 +276,7 @@ struct Impl_DocumentWidget {
275 enum iGmStatusCode sourceStatus; 276 enum iGmStatusCode sourceStatus;
276 iString sourceHeader; 277 iString sourceHeader;
277 iString sourceMime; 278 iString sourceMime;
278 iBlock sourceContent; /* original content as received, for saving */ 279 iBlock sourceContent; /* original content as received, for saving; set on request finish */
279 iTime sourceTime; 280 iTime sourceTime;
280 iGempub * sourceGempub; /* NULL unless the page is Gempub content */ 281 iGempub * sourceGempub; /* NULL unless the page is Gempub content */
281 iGmDocument * doc; 282 iGmDocument * doc;
@@ -1458,7 +1459,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1458 clear_String(&d->sourceMime); 1459 clear_String(&d->sourceMime);
1459 d->sourceTime = response->when; 1460 d->sourceTime = response->when;
1460 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag; 1461 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag;
1461 initBlock_String(&str, &response->body); 1462 initBlock_String(&str, &response->body); /* Note: Body may be megabytes in size. */
1462 if (isSuccess_GmStatusCode(statusCode)) { 1463 if (isSuccess_GmStatusCode(statusCode)) {
1463 /* Check the MIME type. */ 1464 /* Check the MIME type. */
1464 iRangecc charset = range_CStr("utf-8"); 1465 iRangecc charset = range_CStr("utf-8");
@@ -1470,6 +1471,12 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1470 while (nextSplit_Rangecc(mime, ";", &seg)) { 1471 while (nextSplit_Rangecc(mime, ";", &seg)) {
1471 iRangecc param = seg; 1472 iRangecc param = seg;
1472 trim_Rangecc(&param); 1473 trim_Rangecc(&param);
1474 /* Detect fontpacks even if the server doesn't use the right media type. */
1475 if (isRequestFinished && equal_Rangecc(param, "application/octet-stream")) {
1476 if (detect_FontPack(&d->sourceContent)) {
1477 param = range_CStr(mimeType_FontPack);
1478 }
1479 }
1473 if (equal_Rangecc(param, "text/gemini")) { 1480 if (equal_Rangecc(param, "text/gemini")) {
1474 docFormat = gemini_SourceFormat; 1481 docFormat = gemini_SourceFormat;
1475 setRange_String(&d->sourceMime, param); 1482 setRange_String(&d->sourceMime, param);
@@ -1485,9 +1492,11 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1485 docFormat = plainText_SourceFormat; 1492 docFormat = plainText_SourceFormat;
1486 setRange_String(&d->sourceMime, param); 1493 setRange_String(&d->sourceMime, param);
1487 } 1494 }
1488 else if (equal_Rangecc(param, "application/zip") || 1495 else if (isRequestFinished &&
1496 (equal_Rangecc(param, "application/zip") ||
1489 (startsWith_Rangecc(param, "application/") && 1497 (startsWith_Rangecc(param, "application/") &&
1490 endsWithCase_Rangecc(param, "+zip"))) { 1498 endsWithCase_Rangecc(param, "+zip")))) {
1499 clear_String(&str);
1491 docFormat = gemini_SourceFormat; 1500 docFormat = gemini_SourceFormat;
1492 setRange_String(&d->sourceMime, param); 1501 setRange_String(&d->sourceMime, param);
1493 iString *key = collectNew_String(); 1502 iString *key = collectNew_String();
@@ -1496,23 +1505,21 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1496 appendFormat_String(&str, 1505 appendFormat_String(&str,
1497 cstr_Lang("doc.archive"), 1506 cstr_Lang("doc.archive"),
1498 cstr_Rangecc(baseName_Path(d->mod.url))); 1507 cstr_Rangecc(baseName_Path(d->mod.url)));
1499 if (isRequestFinished) { 1508 if (equal_Rangecc(param, mimeType_FontPack)) {
1500 if (equal_Rangecc(param, mimeType_FontPack)) { 1509 /* Show some information about fontpacks, and set up footer actions. */
1501 /* Show some information about fontpacks, and set up footer actions. */ 1510 iArchive *zip = iClob(new_Archive());
1502 iArchive *zip = iClob(new_Archive()); 1511 if (openData_Archive(zip, &d->sourceContent)) {
1503 if (openData_Archive(zip, &d->sourceContent)) { 1512 iFontPack *fp = new_FontPack();
1504 iFontPack *fp = new_FontPack(); 1513 setUrl_FontPack(fp, d->mod.url);
1505 setUrl_FontPack(fp, d->mod.url); 1514 setStandalone_FontPack(fp, iTrue);
1506 setStandalone_FontPack(fp, iTrue); 1515 if (loadArchive_FontPack(fp, zip)) {
1507 if (loadArchive_FontPack(fp, zip)) { 1516 appendFormat_String(&str, "\n\n%s",
1508 appendFormat_String(&str, "\n\n%s", 1517 cstrCollect_String(infoText_FontPack(fp)));
1509 cstrCollect_String(infoText_FontPack(fp)));
1510 }
1511 const iArray *actions = actions_FontPack(fp);
1512 makeFooterButtons_DocumentWidget_(d, constData_Array(actions),
1513 size_Array(actions));
1514 delete_FontPack(fp);
1515 } 1518 }
1519 const iArray *actions = actions_FontPack(fp);
1520 makeFooterButtons_DocumentWidget_(d, constData_Array(actions),
1521 size_Array(actions));
1522 delete_FontPack(fp);
1516 } 1523 }
1517 } 1524 }
1518 appendCStr_String(&str, "\n\n"); 1525 appendCStr_String(&str, "\n\n");
@@ -1534,6 +1541,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1534 startsWith_Rangecc(param, "audio/")) { 1541 startsWith_Rangecc(param, "audio/")) {
1535 const iBool isAudio = startsWith_Rangecc(param, "audio/"); 1542 const iBool isAudio = startsWith_Rangecc(param, "audio/");
1536 /* Make a simple document with an image or audio player. */ 1543 /* Make a simple document with an image or audio player. */
1544 clear_String(&str);
1537 docFormat = gemini_SourceFormat; 1545 docFormat = gemini_SourceFormat;
1538 setRange_String(&d->sourceMime, param); 1546 setRange_String(&d->sourceMime, param);
1539 const iGmLinkId imgLinkId = 1; /* there's only the one link */ 1547 const iGmLinkId imgLinkId = 1; /* there's only the one link */
@@ -1583,7 +1591,13 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1583 } 1591 }
1584 } 1592 }
1585 if (docFormat == undefined_SourceFormat) { 1593 if (docFormat == undefined_SourceFormat) {
1586 showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode, &response->meta); 1594 if (isRequestFinished) {
1595 d->flags &= ~drawDownloadCounter_DocumentWidgetFlag;
1596 showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode, &response->meta);
1597 deinit_String(&str);
1598 return;
1599 }
1600 d->flags |= drawDownloadCounter_DocumentWidgetFlag;
1587 deinit_String(&str); 1601 deinit_String(&str);
1588 return; 1602 return;
1589 } 1603 }
@@ -1617,6 +1631,7 @@ static void fetch_DocumentWidget_(iDocumentWidget *d) {
1617 clear_ObjectList(d->media); 1631 clear_ObjectList(d->media);
1618 d->certFlags = 0; 1632 d->certFlags = 0;
1619 setLinkNumberMode_DocumentWidget_(d, iFalse); 1633 setLinkNumberMode_DocumentWidget_(d, iFalse);
1634 d->flags &= ~drawDownloadCounter_DocumentWidgetFlag;
1620 d->state = fetching_RequestState; 1635 d->state = fetching_RequestState;
1621 set_Atomic(&d->isRequestUpdated, iFalse); 1636 set_Atomic(&d->isRequestUpdated, iFalse);
1622 d->request = new_GmRequest(certs_App()); 1637 d->request = new_GmRequest(certs_App());
@@ -1712,7 +1727,7 @@ static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float n
1712 moveSpan_SmoothScroll(&d->scrollY, 0, 0); /* clamp position to new max */ 1727 moveSpan_SmoothScroll(&d->scrollY, 0, 0); /* clamp position to new max */
1713 cacheDocumentGlyphs_DocumentWidget_(d); 1728 cacheDocumentGlyphs_DocumentWidget_(d);
1714 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag; 1729 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag;
1715 d->flags &= ~urlChanged_DocumentWidgetFlag; 1730 d->flags &= ~(urlChanged_DocumentWidgetFlag | drawDownloadCounter_DocumentWidgetFlag);
1716 postCommandf_Root( 1731 postCommandf_Root(
1717 as_Widget(d)->root, "document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); 1732 as_Widget(d)->root, "document.changed doc:%p url:%s", d, cstr_String(d->mod.url));
1718} 1733}
@@ -2831,8 +2846,8 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2831 } 2846 }
2832 else if (equalWidget_Command(cmd, w, "document.request.updated") && 2847 else if (equalWidget_Command(cmd, w, "document.request.updated") &&
2833 id_GmRequest(d->request) == argU32Label_Command(cmd, "reqid")) { 2848 id_GmRequest(d->request) == argU32Label_Command(cmd, "reqid")) {
2834 set_Block(&d->sourceContent, &lockResponse_GmRequest(d->request)->body); 2849// set_Block(&d->sourceContent, &lockResponse_GmRequest(d->request)->body);
2835 unlockResponse_GmRequest(d->request); 2850// unlockResponse_GmRequest(d->request);
2836 if (document_App() == d) { 2851 if (document_App() == d) {
2837 updateFetchProgress_DocumentWidget_(d); 2852 updateFetchProgress_DocumentWidget_(d);
2838 } 2853 }
@@ -2855,7 +2870,9 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2855 if (category_GmStatusCode(status_GmRequest(d->request)) == categorySuccess_GmStatusCode) { 2870 if (category_GmStatusCode(status_GmRequest(d->request)) == categorySuccess_GmStatusCode) {
2856 init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y); /* TODO: unless user already scrolled! */ 2871 init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y); /* TODO: unless user already scrolled! */
2857 } 2872 }
2858 d->flags &= ~urlChanged_DocumentWidgetFlag; 2873 iChangeFlags(d->flags,
2874 urlChanged_DocumentWidgetFlag | drawDownloadCounter_DocumentWidgetFlag,
2875 iFalse);
2859 d->state = ready_RequestState; 2876 d->state = ready_RequestState;
2860 postProcessRequestContent_DocumentWidget_(d, iFalse); 2877 postProcessRequestContent_DocumentWidget_(d, iFalse);
2861 /* The response may be cached. */ 2878 /* The response may be cached. */
@@ -4959,6 +4976,15 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4959 drawHLine_Paint(&ctx.paint, topLeft_Rect(bounds), width_Rect(bounds), uiSeparator_ColorId); 4976 drawHLine_Paint(&ctx.paint, topLeft_Rect(bounds), width_Rect(bounds), uiSeparator_ColorId);
4960 } 4977 }
4961 drawChildren_Widget(w); 4978 drawChildren_Widget(w);
4979 if (d->flags & drawDownloadCounter_DocumentWidgetFlag && isRequestOngoing_DocumentWidget(d)) {
4980 const int font = uiLabelLarge_FontId;
4981 const iInt2 sevenSegWidth = measureRange_Text(font, range_CStr("\U0001fbf0")).advance;
4982 drawSevenSegmentBytes_MediaUI(font,
4983 add_I2(mid_Rect(docBounds),
4984 init_I2(sevenSegWidth.x * 4.5f, -sevenSegWidth.y / 2)),
4985 uiTextStrong_ColorId, uiTextDim_ColorId,
4986 bodySize_GmRequest(d->request));
4987 }
4962 /* Alt text. */ 4988 /* Alt text. */
4963 const float altTextOpacity = value_Anim(&d->altTextOpacity) * 6 - 5; 4989 const float altTextOpacity = value_Anim(&d->altTextOpacity) * 6 - 5;
4964 if (d->hoverAltPre && altTextOpacity > 0) { 4990 if (d->hoverAltPre && altTextOpacity > 0) {
@@ -5175,6 +5201,7 @@ void updateSize_DocumentWidget(iDocumentWidget *d) {
5175 invalidate_DocumentWidget_(d); 5201 invalidate_DocumentWidget_(d);
5176} 5202}
5177 5203
5204#if 0
5178iBool findCachedContent_DocumentWidget(const iDocumentWidget *d, const iString *url, 5205iBool findCachedContent_DocumentWidget(const iDocumentWidget *d, const iString *url,
5179 iString *mime_out, iBlock *data_out) { 5206 iString *mime_out, iBlock *data_out) {
5180 if (equal_String(d->mod.url, url) && !isRequestOngoing_DocumentWidget(d)) { 5207 if (equal_String(d->mod.url, url) && !isRequestOngoing_DocumentWidget(d)) {
@@ -5196,6 +5223,7 @@ iBool findCachedContent_DocumentWidget(const iDocumentWidget *d, const iString *
5196 } 5223 }
5197 return iFalse; 5224 return iFalse;
5198} 5225}
5226#endif
5199 5227
5200iBeginDefineSubclass(DocumentWidget, Widget) 5228iBeginDefineSubclass(DocumentWidget, Widget)
5201 .processEvent = (iAny *) processEvent_DocumentWidget_, 5229 .processEvent = (iAny *) processEvent_DocumentWidget_,