Skip to content

Commit

Permalink
Merge branch 'dev' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Dec 4, 2023
2 parents a7470a3 + cee5f32 commit 37ccf13
Show file tree
Hide file tree
Showing 16 changed files with 133 additions and 27 deletions.
10 changes: 5 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
cmake_minimum_required (VERSION 3.9)

project (Lagrange
VERSION 1.17.4
VERSION 1.17.5
DESCRIPTION "A Beautiful Gemini Client"
LANGUAGES C
)
set (COPYRIGHT_YEAR 2023)
if (IOS)
set (PROJECT_VERSION 1.17)
set (IOS_BUNDLE_VERSION 4)
set (IOS_BUILD_DATE "2023-11-04")
set (IOS_BUNDLE_VERSION 6)
set (IOS_BUILD_DATE "2023-12-04")
endif ()
if (ANDROID)
set (PROJECT_VERSION 1.17)
set (ANDROID_BUILD_VERSION b24) # remember to update Gradle, AndroidManifest.xml
set (ANDROID_BUILD_DATE "2023-11-04")
set (ANDROID_BUILD_VERSION b25) # remember to update Gradle, AndroidManifest.xml
set (ANDROID_BUILD_DATE "2023-12-04")
endif ()

# Load modules from the source tree
Expand Down
2 changes: 1 addition & 1 deletion lib/the_Foundation
Submodule the_Foundation updated from a6a8f5 to a96302
44 changes: 42 additions & 2 deletions po/eo.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2023-01-19 04:46+0000\n"
"PO-Revision-Date: 2023-03-30 18:15+0000\n"
"PO-Revision-Date: 2023-11-28 17:14+0000\n"
"Last-Translator: Nikolay Korotkiy <[email protected]>\n"
"Language-Team: Esperanto <http://weblate.skyjake.fi/projects/lagrange/ui/eo/>"
"\n"
Expand Down Expand Up @@ -841,7 +841,7 @@ msgid "heading.upload.id"
msgstr "Rajtigo"

msgid "dlg.upload.id.default"
msgstr "Defaŭlto"
msgstr "Defaŭlta identeco"

# used on mobile
msgid "dlg.upload.file"
Expand Down Expand Up @@ -1316,3 +1316,43 @@ msgstr "Turka"
# A language choice in the Translation dialog.
msgid "lang.uk"
msgstr "Ukraina"

msgid "menu.snip.prefs"
msgstr "Agordi…"

msgid "menu.snip.delete"
msgstr "Forigi"

msgid "snip.name"
msgstr "Nomo:"

msgid "heading.snip.new"
msgstr "Nova fragmento"

msgid "error.ansi"
msgstr "Terminalimitilo"

# Action label
msgid "fontpack.meta.viewfile"
msgstr "Montri dosieron"

msgid "fontpack.export"
msgstr "Montri la ŝablonon fontpack.ini"

msgid "sniped.new"
msgstr "Nova fragmento"

msgid "snip.accept"
msgstr "Konservi fragmenton"

msgid "snip.content"
msgstr "Enhavo:"

msgid "heading.snip.edit"
msgstr "Redakti fragmenton"

msgid "menu.snip.clipboard"
msgstr "Kopii al tondujo"

msgid "menu.snip.edit"
msgstr "Redakti…"
7 changes: 7 additions & 0 deletions res/about/android-version.gmi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
```
# Release notes

## 1.17 (Beta 25)
* Fixed a few small memory leaks.
* Gopher: Detect audio media type from file extension with the `s` item type (it's not always WAV).
* Content that uses `charset=utf-8` is checked for validity. If the encoding is invalid, the content is instead decoded as CP437 (if it has ANSI escapes; possibly it's ASCII art) or just Latin-1.
* Modified rule for when 'text/plain' is assumed to actually be 'text/gemini' based on the file extension.
* Updated dependencies to newer versions (OpenSSL, GNU FriBidi, libiconv, libunistring).

## 1.17 (Beta 24)
* Tabs opened in background are immediately added to the URL history.
* Fixed initial scope of a created identity when using the default selection.
Expand Down
8 changes: 8 additions & 0 deletions res/about/ios-version.gmi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
```
# Release notes

## 1.17 (6)
* Fixed a few small memory leaks.
* Fixed unnecessary copying of data while waiting for an audio buffer to become playable. This potentially caused the operating system to terminate the app due to excessive memory use.
* Gopher: Detect audio media type from file extension with the `s` item type (it's not always WAV).
* Content that uses `charset=utf-8` is checked for validity. If the encoding is invalid, the content is instead decoded as CP437 (if it has ANSI escapes; possibly it's ASCII art) or just Latin-1.
* Modified rule for when 'text/plain' is assumed to actually be 'text/gemini' based on the file extension.
* Updated UI translations.

## 1.17 (4)
* Tabs opened in background are immediately added to the URL history.
* Fixed initial scope of a created identity when using the default selection.
Expand Down
8 changes: 8 additions & 0 deletions res/about/version.gmi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
```
# Release notes

## 1.17.5
* Fixed a few small memory leaks.
* Fixed unnecessary copying of data while waiting for an audio buffer to become playable.
* Gopher: Detect audio media type from file extension with the `s` item type (it's not always WAV).
* Content that uses `charset=utf-8` is checked for validity. If the encoding is invalid, the content is instead decoded as CP437 (if it has ANSI escapes; possibly it's ASCII art) or just Latin-1.
* Remove ANSI escapes from window titles.
* Modified rule for when 'text/plain' is assumed to actually be 'text/gemini' based on the file extension.

## 1.17.4
* Removed automatic horizontal scrolling of wide preformatted blocks. Instead, hold down the Shift key to scroll horizontally with the mouse wheel.
* Fixed an event processing issue where some events were not handled as expected, for instance when opening a link into split view the opened link was not highlighted.
Expand Down
Binary file modified res/lang/eo.bin
Binary file not shown.
15 changes: 11 additions & 4 deletions src/audio/player.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,11 @@ static iRangecc mediaType_(const iString *str) {
return part;
}

static iContentSpec contentSpec_Player_(const iPlayer *d) {
static iContentSpec detectContentSpec_Player_(const iPlayer *d) {
iContentSpec content;
iZap(content);
const size_t dataSize = size_InputBuf(d->data);
iBuffer *buf = iClob(new_Buffer());
open_Buffer(buf, &d->data->data);
iBuffer *buf = NULL;
const iRangecc mediaType = mediaType_(&d->mime);
if (equal_Rangecc(mediaType, "audio/wave") || equal_Rangecc(mediaType, "audio/wav") ||
equal_Rangecc(mediaType, "audio/x-wav") || equal_Rangecc(mediaType, "audio/x-pn-wav")) {
Expand All @@ -499,6 +498,12 @@ static iContentSpec contentSpec_Player_(const iPlayer *d) {
/* TODO: Could try decoders to see if one works? */
content.type = none_DecoderType;
}
if (content.type != none_DecoderType) {
buf = iClob(new_Buffer());
/* This holds a reference to the data block. The decoder runs in a background
thread so it needs its own copy of the data. */
open_Buffer(buf, &d->data->data);
}
if (content.type == wav_DecoderType && dataSize >= 44) {
/* Read the RIFF/WAVE header. */
iStream *is = stream_Buffer(buf);
Expand Down Expand Up @@ -713,6 +718,8 @@ void updateSourceData_Player(iPlayer *d, const iString *mimeType, const iBlock *
break;
}
/* The old parts cannot have changed. */
/* NOTE: The decoder will hold a reference to the data block, which means
appending here will cause a copy-on-write detach to occur. */
appendData_Block(&input->data, constBegin_Block(data) + oldSize, newSize - oldSize);
break;
}
Expand Down Expand Up @@ -769,7 +776,7 @@ iBool start_Player(iPlayer *d) {
return iTrue;
}
#endif
iContentSpec content = contentSpec_Player_(d);
iContentSpec content = detectContentSpec_Player_(d);
if (!content.output.freq) {
return iFalse;
}
Expand Down
15 changes: 11 additions & 4 deletions src/gopher.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ void open_Gopher(iGopher *d, const iString *url) {
return;
}
/* MIME type determined by the item type. */
const iString *reqPath =
collect_String(urlDecodeExclude_String(collectNewRange_String(parts.path), "\t"));
switch (d->type) {
case '0':
setCStr_String(d->meta, "text/plain");
Expand All @@ -261,17 +263,22 @@ void open_Gopher(iGopher *d, const iString *url) {
case 'I':
setCStr_String(d->meta, "image/generic");
break;
case 's':
setCStr_String(d->meta, "audio/wave");
case 's': {
const char *detected = mediaTypeFromFileExtension_String(reqPath);
if (startsWith_CStr(detected, "audio/")) {
setCStr_String(d->meta, detected); /* could be .mp3, for example */
}
else {
setCStr_String(d->meta, "audio/wave");
}
break;
}
default:
setCStr_String(d->meta, "application/octet-stream");
break;
}
d->isPre = iFalse;
open_Socket(d->socket);
const iString *reqPath =
collect_String(urlDecodeExclude_String(collectNewRange_String(parts.path), "\t"));
writeData_Socket(d->socket, cstr_String(reqPath), size_String(reqPath));
if (!isEmpty_Range(&parts.query)) {
iAssert(*parts.query.start == '?');
Expand Down
5 changes: 3 additions & 2 deletions src/media.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,9 @@ iBool setData_Media(iMedia *d, iGmLinkId linkId, const iString *mime, const iBlo
}
pushBack_PtrArray(&d->items[audio_MediaType], audio);
/* Start playing right away. */
start_Player(audio->player);
postCommandf_App("media.player.started player:%p", audio->player);
if (start_Player(audio->player)) {
postCommandf_App("media.player.started player:%p", audio->player);
}
isNew = iTrue;
#endif /* LAGRANGE_ENABLE_AUDIO */
}
Expand Down
25 changes: 23 additions & 2 deletions src/ui/documentwidget.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,7 @@ static void releaseViewDocument_DocumentWidget_(iDocumentWidget *d) {
if (d->view == d->swipeView) {
/* The view is being switched away for swiping, so allocate a new one for the
actual document. */
d->swipeBanner = d->banner;
d->banner = new_Banner();
setOwner_Banner(d->banner, d);
setWidth_Banner(d->banner, documentWidth_DocumentView(d->view));
Expand Down Expand Up @@ -1333,9 +1334,18 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
endsWithCase_Rangecc(fileName, ".markdown")) {
param = range_CStr("text/markdown");
}
else if (endsWithCase_Rangecc(fileName, ".gmi") ||
endsWithCase_Rangecc(fileName, ".gemini")) {
else if ((endsWithCase_Rangecc(fileName, ".gmi") ||
endsWithCase_Rangecc(fileName, ".gemini")) &&
isEmpty_Range(&parts.query)) {
/* The server _probably_ sent us the wrong media type, so assume
they meant this is a Gemtext document based on the file extension.
However, if the query string is present, the server likely knows
what it's doing so only "fix" the type when a query component
was not present. */
param = range_CStr("text/gemini");
/* TODO: A better way to do this would be to preserve the original
media type and force a Gemtext view mode on the document.
(https://github.com/skyjake/lagrange/issues/359) */
}
}
}
Expand Down Expand Up @@ -1567,6 +1577,17 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
}
setFormat_GmDocument(d->view->doc, docFormat);
/* Convert the source to UTF-8 if needed. */
if (equalCase_Rangecc(charset, "utf-8")) {
/* Verify that it actually is valid UTF-8. */
if (!isUtf8_Rangecc(range_String(&str))) {
if (strstr(cstr_String(&str), "\x1b[")) {
charset = range_CStr("cp437"); /* An educated guess. */
}
else {
charset = range_CStr("latin1");
}
}
}
if (!equalCase_Rangecc(charset, "utf-8")) {
set_String(&str,
collect_String(decode_Block(&str.chars, cstr_Rangecc(charset))));
Expand Down
3 changes: 3 additions & 0 deletions src/ui/linkinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ iBool update_LinkInfo(iLinkInfo *d, const iDocumentWidget *doc, iGmLinkId linkId
/* Draw to a buffer, wrapped. */
const int avail = iMax(minWidth_LinkInfo_, maxWidth) - 2 * hPad_LinkInfo_;
iWrapText wt = { .text = range_String(&str), .maxWidth = avail, .mode = word_WrapTextMode };
if (d->buf) {
delete_TextBuf(d->buf);
}
d->buf = new_TextBuf(&wt, uiLabel_FontId, tmQuote_ColorId);
deinit_String(&str);
}
Expand Down
1 change: 1 addition & 0 deletions src/ui/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) {
"open notinline:1 url:%s",
cstr_String(absoluteUrl_String(&iStringLiteral(""), text_InputWidget(url))));
}
delete_String(newUrl);
return iFalse;
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/ui/sidebarwidget.c
Original file line number Diff line number Diff line change
Expand Up @@ -2224,14 +2224,15 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
/* Update the menu before opening. */
/* TODO: This kind of updating is already done above, and in `updateContextMenu_`... */
if (d->mode == bookmarks_SidebarMode) {
/* Remote bookmarks have limitations. */
const iSidebarItem *hoverItem = hoverItem_ListWidget(d->list);
iAssert(hoverItem);
if (!hoverItem) {
return iTrue;
}
const iBookmark *bm = get_Bookmarks(bookmarks_App(), hoverItem->id);
if (isFolder_Bookmark(bm)) {
contextMenu = d->folderMenu;
}
else if (!isVisible_Widget(d->menu)) {
else if (!isVisible_Widget(d->menu)) {
const iBool isRemote = (bm->flags & remote_BookmarkFlag) != 0;
static const char *localOnlyCmds[] = { "bookmark.edit",
"bookmark.delete",
Expand All @@ -2240,7 +2241,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
"bookmark.tag tag:remotesource" };
iForIndices(i, localOnlyCmds) {
setFlags_Widget(as_Widget(findMenuItem_Widget(contextMenu, localOnlyCmds[i])),
disabled_WidgetFlag,
disabled_WidgetFlag, /* Remote bookmarks have limitations. */
isRemote);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ui/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ int ansiFlags_Text(void) {
}

iRegExp *makeAnsiEscapePattern_Text(iBool includeEscChar) {
const char *pattern = "\x1b[[()][?]?([0-9;AB]*?)([ABCDEFGHJKSTfhilmn])";
const char *pattern = "\x1b[[\\(\\)][?]?([0-9;AB]*?)([ABCDEFGHJKSTfhilmn])";
if (!includeEscChar) {
pattern++;
}
Expand Down Expand Up @@ -251,7 +251,7 @@ void drawOutline_Text(int fontId, iInt2 pos, int outlineColor, int fillColor, iR
}
#else
drawRange_Text(fontId, pos, fillColor | fillBackground_ColorId, text);
#endif
#endif
}

iTextMetrics measureWrapRange_Text(int fontId, int maxWidth, iRangecc text) {
Expand Down
4 changes: 3 additions & 1 deletion src/ui/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -1815,7 +1815,9 @@ void resize_MainWindow(iMainWindow *d, int w, int h) {
}

void setTitle_Window(iWindow *d, const iString *title) {
SDL_SetWindowTitle(d->win, cstr_String(title));
iString *clean = collect_String(copy_String(title));
replaceRegExp_String(clean, iClob(makeAnsiEscapePattern_Text(iTrue)), "", NULL, NULL);
SDL_SetWindowTitle(d->win, cstr_String(clean));
iLabelWidget *bar = findChild_Widget(get_Root()->widget, "winbar.title");
if (bar) {
updateText_LabelWidget(bar, title);
Expand Down

0 comments on commit 37ccf13

Please sign in to comment.