chiark / gitweb /
mastodonochrome.git
16 months agoFix title of user_posts files.
Simon Tatham [Sat, 13 Jan 2024 14:09:57 +0000 (14:09 +0000)]
Fix title of user_posts files.

Ahem. Copy-paste error from another constructor function!

16 months agoUpdate to the latest html2text.
Simon Tatham [Sat, 13 Jan 2024 14:09:33 +0000 (14:09 +0000)]
Update to the latest html2text.

Chris just announced it. This time I don't know of any feature I'm
desperately missing, but bug fixes are always helpful.

16 months agoTODO updates, including a bug I just noticed.
Simon Tatham [Sat, 13 Jan 2024 13:34:46 +0000 (13:34 +0000)]
TODO updates, including a bug I just noticed.

16 months agoWhen replying to a post, propagate its spoiler warning.
Simon Tatham [Sat, 13 Jan 2024 13:37:37 +0000 (13:37 +0000)]
When replying to a post, propagate its spoiler warning.

I forgot this yesterday in discussions of a maths problem, and posted
an answer in cleartext. Happily, it wasn't a very hard problem. But it
would have been better if the default had been to repeat the spoiler
text from the parent post; I could always change it manually, but if I
don't want to think very hard, this would more likely be right.

16 months agoHonour server-side defaults when composing a new post.
Simon Tatham [Sat, 13 Jan 2024 11:27:51 +0000 (11:27 +0000)]
Honour server-side defaults when composing a new post.

Now after you set your default language, visibility and sensitivity in
[ESC][Y][O] (or indeed via any other client authenticated to the same
account), they will be used by the posting UI.

16 months agoAbility to set most of your own options.
Simon Tatham [Sat, 13 Jan 2024 10:57:21 +0000 (10:57 +0000)]
Ability to set most of your own options.

For the moment, I've left out the account bio and the extra info
fields, because those both require UI extensions we don't have yet.
Added to TODO.

16 months agoClient request to update your account details.
Simon Tatham [Sat, 13 Jan 2024 10:30:26 +0000 (10:30 +0000)]
Client request to update your account details.

16 months agoRetrieve extra details about your own account.
Simon Tatham [Sat, 13 Jan 2024 10:28:49 +0000 (10:28 +0000)]
Retrieve extra details about your own account.

Turns out that the API data model has two related types: 'Account',
which you can retrieve for anyone, and 'CredentialAccount' which
contains an extra sub-object full of settings you can only set (or
see) for your own account.

In another language I could make those distinct actual data types,
one a subclass of the other adding the extra field. Here, it's easier
to just fudge it a bit, pretending that all Account objects
_optionally_ have the 'source' subobject, and when called on to
retrieve our own record, always doing it via the API call that
provides the extra.

This also introduces a bit of a wrinkle about caching the result - we
_do_ also receive copies of our own Account record in other
contexts (e.g. as the author of a status we posted that reappears in a
feed), and so we have to ensure we don't use those to overwrite our
cached record to delete the source. This is ugly, but I prefer it to
the other option, which is to maintain a _separate_ cache of our own
account record with the extra data, and have to worry about which
version of the rest of it is up to date.

16 months agoPost menu: separate 'sensitive' from 'spoiler text'.
Simon Tatham [Sat, 13 Jan 2024 13:11:55 +0000 (13:11 +0000)]
Post menu: separate 'sensitive' from 'spoiler text'.

Alas, it _is_ possible to tag a post as sensitive but not provide any
spoiler text. I don't think I should make it actually impossible
through the UI of this client, so here's a change to permit it.

But I'm discouraging it as much as possible, by focusing into the
content-warning editor as soon as you mark a post as sensitive. That
way, if you really want an absence of warning, you have to
deliberately refuse to type one and press Return.

16 months agoInitial user-options menus.
Simon Tatham [Fri, 12 Jan 2024 08:04:13 +0000 (08:04 +0000)]
Initial user-options menus.

The one for your own options is currently unimplemented (but it had to
_exist_, because both options menus are launched via the same UI
action, and only the target user id distinguishes the two).

But the one for other users supports following and its suboptions,
blocking, and muting.

16 months agoSimilarly reusable menu line for cycling between options.
Simon Tatham [Fri, 12 Jan 2024 08:25:43 +0000 (08:25 +0000)]
Similarly reusable menu line for cycling between options.

16 months agoMore reusable concept of an editable menu line.
Simon Tatham [Thu, 11 Jan 2024 22:42:41 +0000 (22:42 +0000)]
More reusable concept of an editable menu line.

This refactors a lot of the code from posting.rs into a type that does
all the work of being switchable between a menu line and a single-line
editor.

No functional change (I hope), but it should make it easier to reuse
in other similar options menus.

16 months agoRevise menu width handling via a new trait.
Simon Tatham [Thu, 11 Jan 2024 17:56:26 +0000 (17:56 +0000)]
Revise menu width handling via a new trait.

get_widths has become check_widths, which subsumes the processing done
at every call site, and will be easier to extend to the next thing I
have in mind.

Also, the three width-aligning methods for menu lines are now part of
the MenuKeypressLineGeneral trait. That only has one implementing type
right now, but another one will be along shortly.

16 months agoAdd a trait TextFragmentOneLine.
Simon Tatham [Thu, 11 Jan 2024 17:55:20 +0000 (17:55 +0000)]
Add a trait TextFragmentOneLine.

This is a slight refinement of ordinary TextFragment, to be
implemented by types that render to exactly one line of text always,
as opposed to being able to render to 0 or to more than one. The idea
is that if a type implements this trait, then the compiler can _know_
there's one line of text coming out of its render method, instead of
having to call .iter().exactly_one().unwrap() and think hard about
whether I'm risking a runtime failure.

I could implement this trait for a lot more things in text.rs, but for
the moment, I'm only bothering to put it on the one that I need it for
right now.

16 months agoFix toot length tracking with nontrivial Unicode.
Simon Tatham [Fri, 12 Jan 2024 12:43:53 +0000 (12:43 +0000)]
Fix toot length tracking with nontrivial Unicode.

Somehow I totally forgot to distinguish chars from bytes in
Composer::make_regions(), _and_ forgot to test it. So I had a crash
this morning when editing a toot containing Unicode put the 500-byte
mark midway through a UTF-8 character.

That's wrong for _two_ reasons - firstly, no endpoint in the regions
array ought to be anywhere other than a character boundary, and
secondly, the 500 _byte_ boundary has nothing to do with the toot
length limit in the first place! The 500 _character_ boundary would
have been more to the point.

16 months agoSupport unfolding and refolding of sensitive toots.
Simon Tatham [Wed, 10 Jan 2024 08:41:48 +0000 (08:41 +0000)]
Support unfolding and refolding of sensitive toots.

There's a new highlight type for this, so that it can apply to
InReplyTo lines as well as statuses themselves.

The set of unfolded sensitive statuses needs to be shared between lots
of views of the data, so I've put it in the TuiLogicalState, under a
RefCell so that ActivityStates can all borrow it easily, not just to
look up in but also to modify.

16 months agoAbility to display sensitive toots folded up.
Simon Tatham [Wed, 10 Jan 2024 08:37:34 +0000 (08:37 +0000)]
Ability to display sensitive toots folded up.

Not currently used: all our current DisplayStyleGetters
unconditionally return true from their unfolded method.

This has to apply to the quoted line of a toot in Re: lines, as well
as the full display of the post contents.

16 months agoWrap poll_options into a general display-style trait.
Simon Tatham [Mon, 8 Jan 2024 19:39:58 +0000 (19:39 +0000)]
Wrap poll_options into a general display-style trait.

16 months agoFix panic when extending an empty feed.
Simon Tatham [Thu, 11 Jan 2024 07:59:02 +0000 (07:59 +0000)]
Fix panic when extending an empty feed.

If a file contains nothing but a header and an extensible indicator,
and you press [0] to extend, and that attempt to fetch more items
fails, then the extensible indicator vanishes, and is removed from the
file's list of items. So the 2-line header moves forward one index
slot, into the place where the 3-line indicator was. But on any but
the tiniest screen, your current position was surely on the last line
of the indicator - so now it's out of range of the item now in that
position.

To fix this, I've added a new position fixup function, which is called
whenever we fear our line position might be outside the bounds of the
item it's in. This is called after try_extend, where the problem
actually showed up; it's also called on resize(), in case a file is
newly constructed but one of the statuses in it has been updated from
the server since we last visited.

16 months agoMore ColouredString streamlining.
Simon Tatham [Thu, 11 Jan 2024 07:45:28 +0000 (07:45 +0000)]
More ColouredString streamlining.

By making Paragraph::add() take a general impl ColouredStringCommon,
we can get rid of a lot of no-longer-necessary &.

16 months agoGeneral TODO updates.
Simon Tatham [Tue, 9 Jan 2024 20:01:24 +0000 (20:01 +0000)]
General TODO updates.

Some more details, links etc, plus a bug I just noticed in
favouriting.

16 months agoGet rid of ColouredStringSlice::to_owned() completely.
Simon Tatham [Tue, 9 Jan 2024 06:47:55 +0000 (06:47 +0000)]
Get rid of ColouredStringSlice::to_owned() completely.

It's superseded by the impl of From for ColouredString, which means
now if you want to turn a ColouredStringSlice into an owned string,
you can either say ColouredString::from(slice) or slice.into() at your
option. And I haven't found any cases where I had to use the more
verbose of the two.

16 months agoRemove most uses of ColouredString::slice().
Simon Tatham [Tue, 9 Jan 2024 06:37:44 +0000 (06:37 +0000)]
Remove most uses of ColouredString::slice().

The new flexibility means we don't have to use an explicit method call
to turn a ColouredString into a ColouredStringSlice before passing it
to ColouredString::push_str().

Also, in tui.rs, ratatui_set_string demonstrates that functions
outside the coloured_string module can also be given the flexibility
to take either an owned ColouredString or a slice, by taking an
argument 'impl ColouredStringCommon'.

However, in FileStatusLineFinal::render_highlighted(), where I pass
ColouredStringSlices to a closure, I _couldn't_ do that - closures are
apparently more restricted than ordinary functions in that way. So
that's the one place where I still had to explicitly call .slice().

16 months agoRestructure ColouredString via a common trait.
Simon Tatham [Tue, 9 Jan 2024 06:27:19 +0000 (06:27 +0000)]
Restructure ColouredString via a common trait.

Now ColouredString and ColouredStringSlice both implement the trait
ColouredStringCommon, and as many methods as possible are provided by
that trait, depending only on the unimplemented trait methods to get
the text and colours and &str.

This reduces the amount of code, and also makes points of use more
flexible, because I can implement the common trait not just for both
the actual types, but also references to them.

The only disappointment is that I wasn't able to also fold the four
identical impls of std::ops::Add into one via a single
doubly-quantified impl. But instead I got to deploy my first
macro_rules!, so that's something.

In the next commits I'll clean up now-unnecessary boilerplate at call
sites.

16 months agoFix duplication of items in feeds.
Simon Tatham [Mon, 8 Jan 2024 19:20:54 +0000 (19:20 +0000)]
Fix duplication of items in feeds.

When we request any part of the contents of a feed from the server, it
provides us with followup links we can use to extend the same feed
further into the past or future. But if we're extending it further
into the past than we had, we shouldn't save the future link we get
back, because it's not as good as the future link we already had. And
vice versa.

The effect of this bug was that after extending a feed into the past,
the next extension into the future would start from the past
fragment's future extension and re-retrieve all the items we already
had. And we wouldn't notice, and would store a second copy of all
their ids in our list.

16 months agoSupport showing content warnings.
Simon Tatham [Sun, 7 Jan 2024 21:54:58 +0000 (21:54 +0000)]
Support showing content warnings.

We still don't hide the rest of the post, but this is a start, because
sometimes the poster expects that you've at least _seen_ the warning
text. (For example I saw a post today in which the content warning was
the question part of a joke, and the post body was the punchline.)

16 months agoAdd support for polls in other users' posts.
Simon Tatham [Sun, 7 Jan 2024 22:17:27 +0000 (22:17 +0000)]
Add support for polls in other users' posts.

That is, we can't post them ourselves yet, but we can see them when
other users post them, and vote in them.

16 months agoCheck for new messages on startup.
Simon Tatham [Sun, 7 Jan 2024 08:38:08 +0000 (08:38 +0000)]
Check for new messages on startup.

And beep the user into their mentions feed if there are any, just like
Mono does when you log in.

16 months agoClean up huge piece of duplicated logic in Tui.
Simon Tatham [Sun, 7 Jan 2024 08:37:40 +0000 (08:37 +0000)]
Clean up huge piece of duplicated logic in Tui.

Adding the refresh key to it was more than I could bear.

16 months ago^L to refresh the screen.
Simon Tatham [Sun, 7 Jan 2024 07:30:45 +0000 (07:30 +0000)]
^L to refresh the screen.

In case of corruption. An obvious case of corruption is extraneous
output to the same tty (from an unrelated background process, or from
a rogue dbg! in this program itself). Another one I've been seeing
recently is a mysterious corruption relating to some Unicode
characters that only shows up in tmux on one system. But regardless, I
want to get on with my session after anything like that happens.

16 months agoAnother TODO I thought of.
Simon Tatham [Sun, 7 Jan 2024 07:30:39 +0000 (07:30 +0000)]
Another TODO I thought of.

16 months agoCheckpoint the LDB to disk every few minutes.
Simon Tatham [Sat, 6 Jan 2024 14:16:29 +0000 (14:16 +0000)]
Checkpoint the LDB to disk every few minutes.

That should do a decent job of defending against data loss from
panics, SIGTERM, machine reboots, etc.

16 months agoWhen thrown into Read Mentions, show the new mention.
Simon Tatham [Sat, 6 Jan 2024 13:57:23 +0000 (13:57 +0000)]
When thrown into Read Mentions, show the new mention.

This adds an 'is_interrupt' flag to every change of activity; the only
activity constructor that uses it is mentions(), which uses it to vary
the policy about file positioning. When you enter Read Mentions on
your own initiative, you get the same position you were at before, but
when _thrown_ into it, you go to the new message.

In order to still show the new message when you're _already_ in your
mentions, we remove ReadMentions from the list of activities that
don't cause a reload of ReadMentions.

16 months agoAnd reload the LDB on startup!
Simon Tatham [Sat, 6 Jan 2024 13:29:19 +0000 (13:29 +0000)]
And reload the LDB on startup!

Finally, you can restart the client and have it drop you at your
previous position.

16 months agoSave an "ldb" file in the config directory.
Simon Tatham [Sat, 6 Jan 2024 13:10:33 +0000 (13:10 +0000)]
Save an "ldb" file in the config directory.

This is updated whenever we exit a File. I think that's a reasonable
balance between updating it on every single press of Space when paging
through the file (excessive disk churn), and waiting until the whole
client exits (excessive risk of forgetting to save it at all).

Perhaps an even better idea would be to schedule a timer to checkpoint
the LDB every few minutes if it had changed.

16 months agoPersist the latest read item in the Tui.
Simon Tatham [Sat, 6 Jan 2024 13:34:04 +0000 (13:34 +0000)]
Persist the latest read item in the Tui.

Now it's used to set the initial position when File is constructed,
but there's still no actual effect, because the _position_ from the
last File instance on that feed still takes precedence, and we never
save anything into the Tui without one of those.

16 months agoTrack the latest read item within File's lifetime.
Simon Tatham [Sat, 6 Jan 2024 11:32:09 +0000 (11:32 +0000)]
Track the latest read item within File's lifetime.

Nothing actually uses it yet.

16 months agoMake FileContents store the item ids.
Simon Tatham [Sat, 6 Jan 2024 11:58:18 +0000 (11:58 +0000)]
Make FileContents store the item ids.

This allows it to also search for the index of a specific item.

16 months agoAppend \n when we write out a JSON file.
Simon Tatham [Sat, 6 Jan 2024 13:10:38 +0000 (13:10 +0000)]
Append \n when we write out a JSON file.

I just happened to notice that serde_json::to_string_pretty makes the
result pretty in every way except this one.

16 months agoFix clipping of initial file positions.
Simon Tatham [Sat, 6 Jan 2024 11:57:40 +0000 (11:57 +0000)]
Fix clipping of initial file positions.

It's not enough to just modify the item index - we also have to reset
the line number.

16 months agoWrite configuration files atomically.
Simon Tatham [Fri, 5 Jan 2024 23:35:28 +0000 (23:35 +0000)]
Write configuration files atomically.

This is generally good practice, and clears away a prerequisite for
constantly updating an LDB.

16 months agoApply many uncontroversial style fixes from Clippy.
Simon Tatham [Sat, 6 Jan 2024 00:23:00 +0000 (00:23 +0000)]
Apply many uncontroversial style fixes from Clippy.

I ran 'cargo clippy fix', picked out the changes I didn't disagree
with, and reformatted a few overlong lines that resulted. It's a
combination of redundant clones and borrows, what Clippy considers to
be the antipattern of assert_eq!(boolean, true), and failure to use
the full vocabulary of standard methods like Option::is_none,
Result::is_ok, and the various and_then() or map() etc combinators.

16 months agoClippy fix: borrow the HashMap Entry we want to insert into.
Simon Tatham [Fri, 5 Jan 2024 23:31:21 +0000 (23:31 +0000)]
Clippy fix: borrow the HashMap Entry we want to insert into.

I hadn't known about this method of HashMap at all: you can test
whether a key exists, in such a way that you also get a reference to
the slot you'd want to insert it into if it didn't. Then you don't
need the two hash lookups you would with the more obvious approach of
separately testing for contains_key and then maybe inserting.

16 months agoClippy fix: use write_all to beep.
Simon Tatham [Fri, 5 Jan 2024 22:59:08 +0000 (22:59 +0000)]
Clippy fix: use write_all to beep.

Clippy complains that I used stdout().write(), and although I checked
the error code, I didn't also check whether it had written the full
buffer or only part of it.

But it didn't notice that the buffer was one byte long!

16 months agoClippy fix: rename Config::default().
Simon Tatham [Sat, 6 Jan 2024 08:50:12 +0000 (08:50 +0000)]
Clippy fix: rename Config::default().

Calling it that, Clippy complains that it looks too much like the
method of the Default trait, and suggests I either impl Default or
rename the method. For the moment, I'll rename the method; I don't
know that I have a good use for impl Default right now.

16 months agoFix that horrible loop in the streaming subthread.
Simon Tatham [Fri, 5 Jan 2024 22:55:13 +0000 (22:55 +0000)]
Fix that horrible loop in the streaming subthread.

Clippy complained about it at fatal-error level because it never loops
more than once. I only wrote that loop so I could break it in multiple
places with different return values.

But I've had a better idea for how to write the fiddly bit, thanks to
remembering that Peekable is a thing. This is nicer.

16 months agoEditor: fix handling of abutting scan matches.
Simon Tatham [Fri, 5 Jan 2024 22:26:37 +0000 (22:26 +0000)]
Editor: fix handling of abutting scan matches.

My example test of '#hashtag@mention' _shouldn't_ have highlighted the
mention, because the word character before the @ disqualifies it. But
I was doing the matching on a slice of the string, instead of giving
get_span the whole string and telling it where to start from.

That in turn was because I hadn't bothered to give get_span that
argument. But it's really easy to add! Now done.

16 months agoFix inconsistent colour of visibility keywords.
Simon Tatham [Fri, 5 Jan 2024 22:17:59 +0000 (22:17 +0000)]
Fix inconsistent colour of visibility keywords.

In DetailedStatusDisplay I still had "unlisted" as red, whereas I'd
changed my mind elsewhere.

The easiest fix is to use an actual VisibilityLine object, removing
one place I have to make all these things agree.

16 months agoSupport listing the URLs in a post.
Simon Tatham [Fri, 5 Jan 2024 14:09:59 +0000 (14:09 +0000)]
Support listing the URLs in a post.

I didn't have to trawl RcDom after all (as my TODO item suggested).
All I had to do was to put a mutable reference to a Vec<String> into
OurDecorator, and then that could push URLs on to the vector.

Or rather: firstly I had to do that using a &RefCell<Vec<String>>,
because the same Vec<String> reference had to be passed to the
separate decorator instance spawned for sub-blocks. Secondly that
meant I had to bake a lifetime into the type of OurDecorator (since
the call site must know that the reference to the RefCell went away
when the config object is dropped).

Also, I wanted to exclude the URLs that come from mentions and
hashtags, which meant tracking whether a colour annotation had been
applied to anything inside the link - whether it was already live at
the call to decorate_link_start or was turned on immediately
afterwards.

16 months agoSplit media URLs at w-1 chars, not w.
Simon Tatham [Fri, 5 Jan 2024 12:57:43 +0000 (12:57 +0000)]
Split media URLs at w-1 chars, not w.

This makes no real difference, but now they match the URLs in the text
of posts. In the Python version both split at w, but now that I'm
delegating HTML processing to html2text, that splits overlong words at
the same width it wraps sensible lines to. So I have to either have
them inconsistent or change the media one.

w-1 is more 'Mono' anyway, let's be honest :-)

16 months agoFix last-column glitch in post composition.
Simon Tatham [Fri, 5 Jan 2024 10:13:35 +0000 (10:13 +0000)]
Fix last-column glitch in post composition.

16 months agoMake all the tests compile again (ahem).
Simon Tatham [Fri, 5 Jan 2024 10:27:30 +0000 (10:27 +0000)]
Make all the tests compile again (ahem).

16 months agoFlag readonly mode on the main menu.
Simon Tatham [Fri, 5 Jan 2024 10:12:58 +0000 (10:12 +0000)]
Flag readonly mode on the main menu.

Then I get a reminder of whether I can safely compose embarrassingly
nonsensical test toots, or whether I'm supposed to be being coherent :-)

16 months agoCeremonially delete the Python prototype!
Simon Tatham [Fri, 5 Jan 2024 09:58:28 +0000 (09:58 +0000)]
Ceremonially delete the Python prototype!

We've reached feature parity, although I haven't been running the Rust
version live for more than a few hours so far, so there's still a
possibility of finding a bug the old version lacked.

But it's now actually awkward to have it in the same directory - the
two clients look similar enough that I can accidentally run
'./mastodonochrome' in place of './target/debug/mastodonochrome'
during testing, and then be puzzled when it doesn't behave _quite_ the
same.

So, if I need it in an emergency, I can always recover it from the git
log.

16 months agoRemove an obsolete FIXME comment.
Simon Tatham [Fri, 5 Jan 2024 09:50:59 +0000 (09:50 +0000)]
Remove an obsolete FIXME comment.

Primed extensibility indicators have been working for _days_.

16 months agoSupport highlighting the user name in a UserListEntry.
Simon Tatham [Fri, 5 Jan 2024 09:50:03 +0000 (09:50 +0000)]
Support highlighting the user name in a UserListEntry.

So you can look at a list of followers/favers/boosters and go to
Examine User from there.

16 months agoMore robust handling of fatal errors in sync_channel.
Simon Tatham [Fri, 5 Jan 2024 09:48:58 +0000 (09:48 +0000)]
More robust handling of fatal errors in sync_channel.

They were being squelched with a triple-FIXME comment, probably from
very early in development. Now it seems clear that we just propagate
them up to an 'abort the whole Tui' error, because if that goes wrong
then surely there's a disaster too weird to recover from.

16 months agoTrivial indentation fix.
Simon Tatham [Fri, 5 Jan 2024 09:48:44 +0000 (09:48 +0000)]
Trivial indentation fix.

16 months agoAdd a proper TODO list.
Simon Tatham [Fri, 5 Jan 2024 09:13:25 +0000 (09:13 +0000)]
Add a proper TODO list.

My previous jottings were kept outside source control and not very
organised. This is a version I wouldn't be embarrased about showing to
an outsider!

16 months agoFix rendering glitch when ExtensibleIndicator vanishes.
Simon Tatham [Fri, 5 Jan 2024 06:29:57 +0000 (06:29 +0000)]
Fix rendering glitch when ExtensibleIndicator vanishes.

We'd end up drawing three fewer lines of the top of the revised file
than would have fitted on the screen.

16 months agoAdd feature to show posts by the user you're examining.
Simon Tatham [Fri, 5 Jan 2024 06:25:53 +0000 (06:25 +0000)]
Add feature to show posts by the user you're examining.

16 months agoGet the default language from the locale.
Simon Tatham [Thu, 4 Jan 2024 21:09:36 +0000 (21:09 +0000)]
Get the default language from the locale.

Turns out Rust has a handy crate for that.

16 months agoShow visibility of posts with an extra header.
Simon Tatham [Thu, 4 Jan 2024 20:41:12 +0000 (20:41 +0000)]
Show visibility of posts with an extra header.

Also, changed my mind: 'unlisted' doesn't deserve to be alarming red.
Boring grey is enough.

16 months agoExamine User: compact way of displaying fields.
Simon Tatham [Thu, 4 Jan 2024 20:33:58 +0000 (20:33 +0000)]
Examine User: compact way of displaying fields.

This is much simpler than my previous idea of trying to modify the
HTML DOM to insert the heading at the start of the first paragraph!

16 months agoEditor: keystrokes to go to top/bottom of buffer.
Simon Tatham [Thu, 4 Jan 2024 20:23:12 +0000 (20:23 +0000)]
Editor: keystrokes to go to top/bottom of buffer.

I almost forgot about those until I caught myself doing them in real
Mono today.

16 months agoEditor: scroll to keep the cursor in view.
Simon Tatham [Thu, 4 Jan 2024 20:20:55 +0000 (20:20 +0000)]
Editor: scroll to keep the cursor in view.

16 months agoList modes that shouldn't throw you into mentions.
Simon Tatham [Thu, 4 Jan 2024 20:13:47 +0000 (20:13 +0000)]
List modes that shouldn't throw you into mentions.

16 months agoHighlight media of a status as well as text.
Simon Tatham [Thu, 4 Jan 2024 20:11:26 +0000 (20:11 +0000)]
Highlight media of a status as well as text.

If the status has _only_ media, this will be important!

16 months agoShow what user you're logged in as.
Simon Tatham [Thu, 4 Jan 2024 20:05:16 +0000 (20:05 +0000)]
Show what user you're logged in as.

Useful when testing two dummy accounts on a dev server, but might come
in useful for real people maintaining more than one config directory
as well.

16 months agoFetch the two main feeds on startup.
Simon Tatham [Thu, 4 Jan 2024 19:55:13 +0000 (19:55 +0000)]
Fetch the two main feeds on startup.

Mostly, this fixes missing message beeps. But it also means the UI
won't pause annoyingly the first time I go to one of those feeds.

17 months agoImplement searching within files.
Simon Tatham [Thu, 4 Jan 2024 13:55:28 +0000 (13:55 +0000)]
Implement searching within files.

I think that's now all the functionality from the Python prototype,
and we're ready to switch over!

17 months agoRemove leftover diagnostics.
Simon Tatham [Thu, 4 Jan 2024 13:38:40 +0000 (13:38 +0000)]
Remove leftover diagnostics.

17 months agoSave and restore file positions when changing activity.
Simon Tatham [Thu, 4 Jan 2024 12:24:28 +0000 (12:24 +0000)]
Save and restore file positions when changing activity.

Now you go back to where you last were in the file.

17 months agoStore an actual FileType in File.
Simon Tatham [Thu, 4 Jan 2024 12:54:34 +0000 (12:54 +0000)]
Store an actual FileType in File.

That way it can remember what feed the file is about, so as to save
the file position later.

17 months agoMake new_activity_state a method of TuiLogicalState.
Simon Tatham [Thu, 4 Jan 2024 12:21:18 +0000 (12:21 +0000)]
Make new_activity_state a method of TuiLogicalState.

I got away without it having to be for a long time, but now it's going
to need to fetch file positions.

17 months agoFill in some fixed initial file positions.
Simon Tatham [Thu, 4 Jan 2024 12:16:22 +0000 (12:16 +0000)]
Fill in some fixed initial file positions.

Examine User and Post Info should start at the top, not the bottom,
now that we have the ability to do that easily.

And when you view the thread of a post, it makes sense to me to focus
_that post_ to start with!

17 months agoAdd an initial_pos to the File constructor.
Simon Tatham [Thu, 4 Jan 2024 11:58:51 +0000 (11:58 +0000)]
Add an initial_pos to the File constructor.

17 months agoRework FilePosition to cache the last known width.
Simon Tatham [Thu, 4 Jan 2024 11:38:40 +0000 (11:38 +0000)]
Rework FilePosition to cache the last known width.

This way, it doesn't have to eagerly throw away its 'fine' position:
it can keep it until it's next called on, and then reuse it if the
new render width happens to match.

I think it's also simpler than the previous approach!

17 months agoFix extending user-list feeds.
Simon Tatham [Thu, 4 Jan 2024 10:42:36 +0000 (10:42 +0000)]
Fix extending user-list feeds.

In lists of followers, favers, boosters etc, the ids you have to pass
in the 'max_id' or 'since_id' URL query parameters are not the same as
the account ids you get back. That's not surprising, now I think about
it, since the chronological order in which users did things has
nothing to do with any intrinsic ordering on the users themselves.

For status feeds, they seemed to match, so I got away without having
to pay attention to the Link: headers in the HTTP responses. But now I
realise I do have to worry about that after all. Happily, there's a
handy Rust crate that saves me having to do the work of parsing that
complicated header type!

17 months agoCLI option to log HTTP transactions to a file.
Simon Tatham [Thu, 4 Jan 2024 10:17:27 +0000 (10:17 +0000)]
CLI option to log HTTP transactions to a file.

This allows me to actually see what's going on when the client
misbehaves.

17 months agoCreate a log entry for every HTTP transaction.
Simon Tatham [Thu, 4 Jan 2024 09:50:52 +0000 (09:50 +0000)]
Create a log entry for every HTTP transaction.

These are built into a struct and passed to a 'consume' method which
currently does nothing with them.

In the immediate short term, I want to add a --debug option which
writes them to a log file on disk, so I can look at a misbehaving
session and see what went wrong.

In the longer term, I think I might also want to keep a rolling buffer
of these log entries, and make it accessible through the Logs Menu.

17 months agoFold the send() into Client::api_request.
Simon Tatham [Thu, 4 Jan 2024 09:08:46 +0000 (09:08 +0000)]
Fold the send() into Client::api_request.

One fewer line of faff at every call site. Plus, now I can centralise
logging usefully.

17 months agoImplement the various user lists.
Simon Tatham [Thu, 4 Jan 2024 08:30:49 +0000 (08:30 +0000)]
Implement the various user lists.

Lists of users who followed or boosted a given post, or who a given
user follows or is followed by.

But something goes wrong when you try to extend these feeds. I'll
debug that in a moment ... but first, let's write some debugging
framework.

17 months agoImplement replying to posts.
Simon Tatham [Thu, 4 Jan 2024 08:09:21 +0000 (08:09 +0000)]
Implement replying to posts.

This involves a new Post constructor that fills in in_reply_to,
propagates visibility, and populates the post text with appropriate
@mentions; and a new pair of activities (these ones Util rather than
non-Util) to pass the reply back and forth between the composer and
the post-compose menu.

17 months agoMove some code into an InReplyToLine::from_id constructor.
Simon Tatham [Thu, 4 Jan 2024 07:38:26 +0000 (07:38 +0000)]
Move some code into an InReplyToLine::from_id constructor.

That will make it easier to reuse later.

17 months agoImplement viewing the thread of a selected post.
Simon Tatham [Thu, 4 Jan 2024 08:06:15 +0000 (08:06 +0000)]
Implement viewing the thread of a selected post.

Just as in the Python version, I provide an extra convenience method
which calls the API service twice, once to find the post's ultimate
top-level ancestor, and then again on that post to show the full
thread (maximal connected component) that it's a part of, not just its
own particular line.

17 months agoGeneralise SingletonSource to hold a whole vector.
Simon Tatham [Thu, 4 Jan 2024 07:42:16 +0000 (07:42 +0000)]
Generalise SingletonSource to hold a whole vector.

The previous new() constructor is now a singleton(), so it can still
work for its current purpose.

17 months agoImplement favouriting and boosting posts.
Simon Tatham [Thu, 4 Jan 2024 08:02:03 +0000 (08:02 +0000)]
Implement favouriting and boosting posts.

For these uses of selection, we have to support different keystrokes
to fave and unfave, which means we also need to know which keystroke
is valid when. So I've had to plumb the Client through to all of the
methods that move the selection, because those methods need to
retrieve the newly pointed-to status and cache whether it's already
faved/boosted. Otherwise draw(), which can't mutate things, can't
find that out to display the right status line.

17 months agoImplement selecting things in File.
Simon Tatham [Thu, 4 Jan 2024 07:45:08 +0000 (07:45 +0000)]
Implement selecting things in File.

This makes the [E] and [I] keystrokes begin working in general, to
examine a selected user and to view the full info for a selected
status.

17 months agoFactor out feed extension code into a method of File.
Simon Tatham [Thu, 4 Jan 2024 07:48:00 +0000 (07:48 +0000)]
Factor out feed extension code into a method of File.

Mostly just because it's large and cumbersome and it's nice to keep
the key-handling match cases short.

17 months agoActually implement the highlighting methods!
Simon Tatham [Thu, 4 Jan 2024 07:39:44 +0000 (07:39 +0000)]
Actually implement the highlighting methods!

Everything up to here just added API. Now I'm actually providing
non-default implementations so that TextFragments that need to
highlight can be highlighted.

17 months agoStore ids in all the TextFragments that will need them.
Simon Tatham [Thu, 4 Jan 2024 07:36:52 +0000 (07:36 +0000)]
Store ids in all the TextFragments that will need them.

The method of finding out _what_ thing was highlighted has to return
it by its string id. So anything that will have to highlight a
contained object will also need a way to return its id, so they all
have to store those ids.

17 months agoAdd highlighting methods to the TextFragment trait.
Simon Tatham [Thu, 4 Jan 2024 07:30:41 +0000 (07:30 +0000)]
Add highlighting methods to the TextFragment trait.

I've chosen to have three rather than two classes of thing you can
highlight, by separately indicating whether a text fragment contains
highlightable 'statuses' or 'whole statuses'. The distinction is that
a 'whole status' means you can see all the text, whereas a 'status'
just means you can somehow identify which post it is. I'll use that to
arrange that replying, favouriting and boosting only apply to whole
statuses (too easy to make a mistake otherwise), whereas any 'get
more info' commands apply to any old status.

(In particular, this way, you can see a one-line summary of a status,
press [I] to look at the whole thing, and _then_ fave/boost/reply.)

17 months agoTidy up: make Option and Vec pass through TextFragment.
Simon Tatham [Thu, 4 Jan 2024 07:26:14 +0000 (07:26 +0000)]
Tidy up: make Option and Vec pass through TextFragment.

Now if you have an Option<TextFragment>, or a Vec<TextFragment> (or
even, heaven help you, an Option<Vec> or a Vec<Option<Vec>> etc), you
can just call .render() on the whole thing without having to manually
loop over it. I'm starting to like this feature of Rust!

17 months agoWhen caching a status, cache its reblog too.
Simon Tatham [Wed, 3 Jan 2024 16:26:46 +0000 (16:26 +0000)]
When caching a status, cache its reblog too.

That's another whole status, which we should be able to look up.

17 months agoReclassify status info as a utility activity.
Simon Tatham [Wed, 3 Jan 2024 13:40:51 +0000 (13:40 +0000)]
Reclassify status info as a utility activity.

I meant it to be that in the first place - that's why I entered
InfoStatus in the utilities enum. But then I forgot it was there and
made a separate entry for it.

When you're invoking status info from within a file, I think it makes
more sense as a utility, the way I first had it.

17 months agoSupport saving login details. We can now log in!
Simon Tatham [Wed, 3 Jan 2024 10:55:39 +0000 (10:55 +0000)]
Support saving login details. We can now log in!

17 months agoMove TopLevelError up to the root of the crate.
Simon Tatham [Wed, 3 Jan 2024 10:55:17 +0000 (10:55 +0000)]
Move TopLevelError up to the root of the crate.

If that's not a candidate for putting at the top level then I don't
know what is.

17 months agoImplement the login procedure, without saving.
Simon Tatham [Wed, 3 Jan 2024 08:19:37 +0000 (08:19 +0000)]
Implement the login procedure, without saving.

Currently, the JSON-serialised AuthConfig is written to stdout, just
to prove during development that it works. Next step is to save it to
where it ought to live.

17 months agoActually post something!
Simon Tatham [Wed, 3 Jan 2024 07:18:14 +0000 (07:18 +0000)]
Actually post something!