summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ui/documentwidget.c78
-rw-r--r--src/ui/documentwidget.h4
-rw-r--r--src/ui/mediaui.c11
-rw-r--r--src/ui/mediaui.h2
4 files changed, 63 insertions, 32 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_,
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h
index 9bfab57a..2df3392b 100644
--- a/src/ui/documentwidget.h
+++ b/src/ui/documentwidget.h
@@ -48,8 +48,8 @@ const iString * bookmarkTitle_DocumentWidget (const iDocumentWidget *);
48const iString * feedTitle_DocumentWidget (const iDocumentWidget *); 48const iString * feedTitle_DocumentWidget (const iDocumentWidget *);
49int documentWidth_DocumentWidget (const iDocumentWidget *); 49int documentWidth_DocumentWidget (const iDocumentWidget *);
50 50
51iBool findCachedContent_DocumentWidget(const iDocumentWidget *, const iString *url, 51//iBool findCachedContent_DocumentWidget(const iDocumentWidget *, const iString *url,
52 iString *mime_out, iBlock *data_out); 52// iString *mime_out, iBlock *data_out);
53 53
54enum iDocumentWidgetSetUrlFlags { 54enum iDocumentWidgetSetUrlFlags {
55 useCachedContentIfAvailable_DocumentWidgetSetUrlFlag = iBit(1), 55 useCachedContentIfAvailable_DocumentWidgetSetUrlFlag = iBit(1),
diff --git a/src/ui/mediaui.c b/src/ui/mediaui.c
index d85d0df9..4f2499b0 100644
--- a/src/ui/mediaui.c
+++ b/src/ui/mediaui.c
@@ -198,7 +198,7 @@ void draw_PlayerUI(iPlayerUI *d, iPaint *p) {
198 198
199/*----------------------------------------------------------------------------------------------*/ 199/*----------------------------------------------------------------------------------------------*/
200 200
201static void drawSevenSegmentBytes_(iInt2 pos, int color, size_t numBytes) { 201void drawSevenSegmentBytes_MediaUI(int font, iInt2 pos, int majorColor, int minorColor, size_t numBytes) {
202 iString digits; 202 iString digits;
203 init_String(&digits); 203 init_String(&digits);
204 if (numBytes == 0) { 204 if (numBytes == 0) {
@@ -221,12 +221,11 @@ static void drawSevenSegmentBytes_(iInt2 pos, int color, size_t numBytes) {
221 magnitude++; 221 magnitude++;
222 } 222 }
223 if (magnitude > 6) { 223 if (magnitude > 6) {
224 prependCStr_String(&digits, uiTextStrong_ColorEscape); 224 prependCStr_String(&digits, escape_Color(majorColor));
225 } 225 }
226 } 226 }
227 const int font = uiLabel_FontId;
228 const iInt2 dims = measureRange_Text(font, range_String(&digits)).bounds.size; 227 const iInt2 dims = measureRange_Text(font, range_String(&digits)).bounds.size;
229 drawRange_Text(font, addX_I2(pos, -dims.x), color, range_String(&digits)); 228 drawRange_Text(font, addX_I2(pos, -dims.x), minorColor, range_String(&digits));
230 deinit_String(&digits); 229 deinit_String(&digits);
231} 230}
232 231
@@ -267,7 +266,9 @@ void draw_DownloadUI(const iDownloadUI *d, iPaint *p) {
267 isFinished ? uiTextAction_ColorId : uiTextDim_ColorId, 266 isFinished ? uiTextAction_ColorId : uiTextDim_ColorId,
268 cstr_Lang(isFinished ? "media.download.complete" : "media.download.warnclose")); 267 cstr_Lang(isFinished ? "media.download.complete" : "media.download.warnclose"));
269 const int x2 = right_Rect(rect); 268 const int x2 = right_Rect(rect);
270 drawSevenSegmentBytes_(init_I2(x2, y1), uiTextDim_ColorId, info.numBytes); 269 drawSevenSegmentBytes_MediaUI(uiLabel_FontId, init_I2(x2, y1),
270 uiTextStrong_ColorId, uiTextDim_ColorId,
271 info.numBytes);
271 const iInt2 pos = init_I2(x2, y2); 272 const iInt2 pos = init_I2(x2, y2);
272 if (bytesPerSecond > 0) { 273 if (bytesPerSecond > 0) {
273 drawAlign_Text(uiLabel_FontId, pos, uiTextDim_ColorId, right_Alignment, 274 drawAlign_Text(uiLabel_FontId, pos, uiTextDim_ColorId, right_Alignment,
diff --git a/src/ui/mediaui.h b/src/ui/mediaui.h
index 3d51e4c9..15c6e2ce 100644
--- a/src/ui/mediaui.h
+++ b/src/ui/mediaui.h
@@ -31,6 +31,8 @@ iDeclareType(Paint)
31iDeclareType(Player) 31iDeclareType(Player)
32iDeclareType(PlayerUI) 32iDeclareType(PlayerUI)
33 33
34void drawSevenSegmentBytes_MediaUI (int font, iInt2 pos, int majorColor, int minorColor, size_t numBytes);
35
34struct Impl_PlayerUI { 36struct Impl_PlayerUI {
35 const iPlayer *player; 37 const iPlayer *player;
36 iRect bounds; 38 iRect bounds;