| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
| |
The runewidth module only allows truncating at the end of strings. Add
a function to truncate at the beginning. It will be used for the table
widget in the next commit.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
|
| |
Add functions and fields in preparation for more than only message
templates. The idea is to reuse the same symbols for the message list
format and other parts of the UI.
Update the man page accordingly.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
| |
No need to pre-render fields that are not necessarily accessed in
templates. Change fields to functions that are evaluated only when
required.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
| |
This makes room in preparation for more code in here.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
| |
Instead of accepting any garbage for these configuration fields, parse
them when parsing accounts.conf and store mail.Address objects. Reuse
these objects everywhere.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
| |
Use go ini reflection capabilities where possible. Mark fields that can
be trivially parsed and those who need manual parsing. Restrict
backend-specific parameters to ini keys that are not listed as ini
struct field tags.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
| |
Using a list of integers is not optimal. Use a bit mask instead.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
| |
Add `:send -a flat|month|year` to send, which archives the message being
replied to. Extract most of archive logic into a separate function to
make sure it behaves as manual archiving.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
| |
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
| |
Seen with git 2.34:
error: unknown option `empty=drop'
Check the patch file manually instead and abort early.
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When scrolling while the thread builder is running, aerc freezes. This
issue can be easily reproduced by keeping the down arrow pressed while
a folder is loading with local threading enabled.
This is caused by the threadCallback function calling store.Select which
acquires threadsMutex. However, threadCallback is already called with
threadsMutex acquired, causing a deadlock.
Fix the issue by adding a new selectPriv function that does not acquire
the lock and call this one in threadCallback *and* store.Select. Do not
reset threadCallback to nil as it was before.
Fixes: 6b8e0b19d35a ("split: refactor to prevent stuck splits")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Thomas Vigouroux <me@vigoux.giize.com>
|
|
|
|
|
|
|
|
| |
Obviously, this is not exhaustive. But these should be most user visible
changes.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Pressing up while in command mode, calls TextInput.Set() with the
previous command in the history. If the command exceeds the current
terminal width, there is a scroll mechanism that puts the cursor at the
end of the text (see ensureScroll()). However, the offset used to
perform the draw is not the current scroll value but the "previous" one.
When the one before last command required a longer scroll offset than
the current command length, this causes a crash:
Error: runtime error: slice bounds out of range [348:5]
git.sr.ht/~rjarry/aerc/lib/ui.(*TextInput).Draw(0xc0017ce000, 0xc005460570)
git.sr.ht/~rjarry/aerc/lib/ui/textinput.go:111 +0x525
git.sr.ht/~rjarry/aerc/widgets.(*ExLine).Draw(0x30?, 0xc01de13b08?)
git.sr.ht/~rjarry/aerc/widgets/exline.go:76 +0x1d
git.sr.ht/~rjarry/aerc/lib/ui.(*Stack).Draw(0xc0003f0ff0?, 0x0?)
git.sr.ht/~rjarry/aerc/lib/ui/stack.go:30 +0x49
git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).Draw(0xc00038c240, 0xc0003f0ff0)
git.sr.ht/~rjarry/aerc/lib/ui/grid.go:126 +0x225
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).Draw(0xc0003f4000, 0xc0003f0ff0)
git.sr.ht/~rjarry/aerc/widgets/aerc.go:176 +0x1d2
git.sr.ht/~rjarry/aerc/lib/ui.(*UI).Render(0xc0003a0000)
git.sr.ht/~rjarry/aerc/lib/ui/ui.go:110 +0x63
main.main()
git.sr.ht/~rjarry/aerc/aerc.go:255 +0x9c5
There are actually two distinct issues here:
1) The scroll offset used for drawing must be the current one, not the
one from the previous ensureScoll() call.
2) The scroll offset must be reset when changing the text with
TextInput.Set(). Other methods that change the text actually call
ensureScroll but they make incremental changes to the text, since Set
completely overwrites everything, it makes more sense to set the
scroll offset to 0.
Reported-by: Adam Cooper <adam@theadamcooper.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
| |
According to scdoc(5), numbered lists start with a period.
Fixes: af63bd0188d1 ("doc: homogenize scdoc markup")
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 6b8e0b19d35a ("split: refactor to prevent stuck splits")
introduced a regression where a split message viewer is not closed when
a new message is selected, leading to every split view staying open in
the background.
Fixes: 6b8e0b19d35a ("split: refactor to prevent stuck splits")
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
| |
Upgrade tcell-term to latest tag. Has only a few fixes:
- Always set TERM=xterm-256color for better compatibility
- Fix some RGB parsing sequences
- Fix splitting of UTF8 bytes causing render issues
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
| |
Fix typos in aerc-config man page.
Signed-off-by: Folker Schwesinger <dev@folker-schwesinger.de>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
| |
Refactor split logic (again...) to prevent stuck splits. Use callback
from msgstore.Select to tell the split which message to display. This
keeps the account from having to track displayed messages, which
prevents race conditions in certain situations.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a "terminal" theme to colorize script. The "terminal" theme respects
the users' configured terminal color scheme. Also links are blue
underlined.
Usage:
colorize -v theme=terminal
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The SMTP configuration is slightly different between oauthbearer and
xoauth2. The oauthbearer requires a token-endpoint, while xoauth2 does
not. The IMAP version of oauthbearer also does not require a
token-endpoint. If one is specified, the token is treated as a refresh
token.
Modify the SMTP usage to work the same way: a token is an access token
unless a token-endpoint is specified
Reported-by: Cameron Samak <csamak@apache.org>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
| |
Avoid errors by checking cover letters as regular patches.
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Most of the time it is not wanted to attach hidden files, but by default
globbing does include hidden files.
Add a small check that removes hidden files from the results if they are
not explicitly globbed for or inside a hidden directory.
Implements: https://todo.sr.ht/~rjarry/aerc/83
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
| |
This is less important than reporting actual coding errors.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
| |
We don't care that they are known in .mailmap as long as both match.
Reported-by: Moritz Poldrack <moritz@poldrack.dev>
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When entering passwords from a password-manager the wizard shows it's
warning right after the first character has been pasted and the rest of
the password is lost.
Debounce the displaying of the "stored in plaintext"-warning to only
show after the password has been entered.
Reported-by: qbit (@qbit:tapenet.org)
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When using :new-account, aerc crashes when entering a letter with the
following trace:
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x66930e]
goroutine 1 [running]:
git.sr.ht/~rjarry/aerc/log.PanicHandler()
git.sr.ht/~rjarry/aerc/log/panic-logger.go:51 +0x73e
panic({0xa2b200, 0x10204e0})
runtime/panic.go:890 +0x262
git.sr.ht/~rjarry/aerc/config.(*KeyBindings).GetBinding(0xc000370000?, {0xc000634c48?, 0xc000118900?, 0x5843da?})
git.sr.ht/~rjarry/aerc/config/binds.go:331 +0x2e
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).Event(0xc000370000, {0xbd1e60?, 0xc00112e000?})
git.sr.ht/~rjarry/aerc/widgets/aerc.go:309 +0x196
git.sr.ht/~rjarry/aerc/lib/ui.(*UI).HandleEvent(0xc00031e840, {0xbd1e60?, 0xc00112e000})
git.sr.ht/~rjarry/aerc/lib/ui/ui.go:141 +0x162
main.main()
git.sr.ht/~rjarry/aerc/aerc.go:246 +0xa89
The issue is that the keyNames map is empty when defaultBindsConfig() is
called and ParseBinding("<C-q>", ":quit<Enter>") returns an error:
Unknown key 'C-q' which is (unfortunately) ignored and nil is inserted
in the wizard bindings.
Fix that by initializing keyNames at the module level and remove init().
Fixes: c05c2ffe0424 ("config: make various sections accessible via global vars")
Reported-by: Moritz Poldrack <moritz@poldrack.dev>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Guessing a width/height with v?split is rather bothersome, using a
sensible value based on the user's terminal would be preferable. This
also prevents confusion when running :v?split without a number seemingly
does not open a split.
Initialize width as half the width of the message list and height as an
eight of the message list.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
| |
This will be reused in next commit.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
| |
This is useless and annoying.
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the patch fails to apply, users may get an obscure error from git:
error: sha1 information is lacking or useless (commands/msg/reply.go).
error: could not build fake ancestor
Add explicit error messages indicating what happened and what should be
done.
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
| |
Previously close-on-reply was implemented as a setting, making it
unflexible. Refactor so it is a flag to reply `:reply -c`.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
| |
In addition of digits, handle lower case letters as list items:
a) foo
b) baz
c) bar
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a gitconfig target in the Makefile to configure a new clone with
sane defaults:
- set subject prefix
- set correct mailing list address
- enable sendemail.validate
- install sendemail-validate hook
The sendemail-validate hook will make a shallow clone of the current
upstream repo, apply every patch on it and run some checks (a stripped
down version of what is run by the upstream CI).
Add a new check-patches script that verifies that the commit message
actually contains something and that the Signed-off-by trailer from the
patch author is present.
Call check-patches in both the CI and the sendemail-validate hook.
Update CONTRIBUTING.md accordingly.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
| |
Set a default flag character for icon-attachment to match the man page.
Fixes: adf74be4b5c5 ("msglist: add attachment indicator")
Signed-off-by: Ben Cohen <ben@bencohen.net>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The addition of the iterator factory added a thread builder when using
server side threads. A conditional for returning UIDs when selecting
messages would check for a not-nil store.builder, and return UIDs from
the thread builder. When using server side threads, there was no
mechanism to update the threads after a message deletion or move, so
store.Uids() would return a stale set of UIDs. This would allow the user
to "select" a deleted email (the cursor would disappear).
Add an update mechanism for the threads if server side threads are
enabled. When building thread UIDs, check for deleted or hidden threads.
Fixes: https://todo.sr.ht/~rjarry/aerc/123
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Inwit <inwit@sindominio.net>
|
|
|
|
|
|
|
|
| |
Install styles along with aerc. Include stylesets from the wiki and
Robin's pink/blue.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
| |
Currently it's not possible to define combinations of marked and
searched. Since searched messages are just a convenience, while marked
message can be operated upon, make sure that when a message is both
marked and a search result the marked styleset is applied.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
| |
The introduction of the iterator means the "next" non-deleted message is
never nil, it will always be equal to the previous message (meaning
there is only one message left and it is the one we are deleting). In
this case, deliberately set next to nil so that the remove tab on delete
logic works properly.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Refactor split update logic to more simply update the split. Through the
evolution of the split logic, additional variables were stored within
the account which allows for cleaner updating of the split.
Compare selected UID instead of pointer to message when deciding not to
update split.
Allow splits to be created and closed when no message is selected. The
split will be filled with a ui.Fill (blank). The user will only see a
border at the split location when no message is selected.
Rename clearSplit to closeSplit, as it is only used in the case when the
user doesn't want a split anymore.
Ensure that the selected UID is reset to the magic UID when there are no
messages left in the message store.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The maildir worker sends a MessagesMoved message to the UI when messages
are moved, enabling the destination directory to update it's counts. The
filesystem watcher sees the move and updates the directory currently
selected. However, an update of the UIDs in the msgstore is not
completed as it is in other workers. All other works, via some mechanism
(direct or EXPUNGE update) issue a MessagesDeleted message after a move.
Send this message to the UI for the maildir worker to have it work as
all other workers do.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
| |
Add indicator of an attachment to the flags and make the character used
to be configurable.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Tested-by: Jens Grassel <jens@wegtam.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There is only one instance of AercConfig which is associated to the Aerc
widget. Everywhere we need to access configuration options, we need
somehow to get a reference either to the Aerc widget or to a pointer to
the AercConfig instance. This makes the code cluttered.
Remove the AercConfig structure and every place where it is referenced.
Instead, declare global variables for every configuration section and
access them directly from the `config` module.
Since bindings and ui sections can be "contextual" (i.e. per account,
per folder or per subject), leave most local references intact.
Replacing them with config.{Ui,Binds}.For{Account,Folder,Subject} would
make this patch even more unreadable. This is something that may be
addressed in the future.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The current contextual binds and ui config API is awkward and cumbersome
to use. Rework it to make it more elegant.
Store the contextual sections as private fields of the UIConfig and
KeyBindings structures. Add cache to avoid recomputation of the composed
UIConfig and KeyBindings objects every time a contextual item is
requested. Replace the cache from DirectoryList with that.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
| |
Process shortlog stats for Acked-by, Reviewed-by and Tested-by trailers.
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a new :multipart command that can be executed on the composer review
screen. This command takes a MIME type as argument which needs to match
a setting in the new [multipart-converters] section of aerc.conf. A part
can be removed by using the -d flag.
The [multipart-converters] section has MIME types associated with
commands. These commands are executed with sh -c every time the main
email body is updated to generate each part content. The commands are
expected to output valid UTF-8 text.
If a command fails, an explicit error will be printed next to the part
MIME type to allow users to debug their issue but the email may still be
sent anyway with an empty alternative part.
This is mostly intended for people who *really* need to send html
messages for their boss or for corporate reasons. For now, it is
a manual and explicit action to convert a message in such a way.
Here is an example configuration:
[multipart-converters]
text/html = pandoc -f markdown -t html
And the associated binding to append an HTML alternative to a message:
[compose::review]
H = :multipart text/html<enter>
hh = :multipart -d text/html<enter>
Link: https://lists.sr.ht/~rjarry/aerc-discuss/%3CCO5KH4W57XNB.2PZLR1CNFK22H%40mashenka%3E
Co-authored-by: Eric McConville <emcconville@emcconville.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit b46e57324394 ("store: fix server-side threads toggling")
introduced a regression where the uids of the store were not set after
rebuilding the threads. This would result in a flash of pending messages
as they were repopulated. This also would not properly remove messages
which were moved out of the store (deleted, moved, archived) with server
side threading.
Re-add the line that sets the store.uids.
Fixes: b46e57324394 ("store: fix server-side threads toggling")
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
| |
When using aerc > log, print all messages as it was before the logging
system cleanup.
Requested-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
| |
Change the default provider to gpg unless the internal keyring is
initialized and contains one key.
This should be more user friendly.
Link: https://lists.sr.ht/~rjarry/aerc-discuss/%3CCO783CI3IU9F.184DBQTPMIPBS%40paul%3E
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
| |
Instead of obscure descriptions for the settings format, add a synopsis
for all settings in the man pages.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I had started writing this as an awk script but quickly got stuck with
obscure code which did not even work properly. I jumped the gun and re
did it in go. Bonus, we will not have MacOS's 1987 BSD awk issues. On
the other hand, instead of a 20.0K awk script, we now have a 2.2M static
go binary. If this makes people scream, I challenge them to do that with
BSD awk :)
Basically, this takes text from stdin or from a file and wraps long
lines on word boundaries. It takes care of not breaking up email quotes
nor list items (numbered as well). Also, it is conservative by default
and only wraps long lines and lines that end with a space (indicating
a format=flowed message).
If the AERC_SUBJECT environment variable is defined and contains the
word PATCH, the text is not modified at all (i.e. wrap behaves as
cat(1)).
There are a few command line options to control behavior:
Usage of ./wrap:
-f string
read from file instead of stdin
-l int
minimum percentage of letters in a line to be considered
a paragaph (default 50)
-r reflow all paragraphs even if no trailing space
-w int
preferred wrap margin (default 80)
Update docs, makefile and default config file with examples.
Add a torture test to ensure it works as expected.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|