chiark / gitweb /
mastodonochrome.git
15 months agocoloured_string: Make ColouredString common blanket impl for & wip.ref
Ian Jackson [Sun, 4 Feb 2024 14:20:45 +0000 (14:20 +0000)]
coloured_string: Make ColouredString common blanket impl for &

This also avoids repeating the (trivial) field accessor bodies.

15 months agocoloured_string: Simplify a macro
Ian Jackson [Sun, 4 Feb 2024 14:09:14 +0000 (14:09 +0000)]
coloured_string: Simplify a macro

We can use a non-elided anonymous lifetime here, which makes the macro
a lot simpler.

15 months agoOnly display _nonzero_ follow-request counts.
Simon Tatham [Sat, 3 Feb 2024 12:09:25 +0000 (12:09 +0000)]
Only display _nonzero_ follow-request counts.

Ahem. Of course I initially tested this in the difficult case, and
forgot to check the easy one :-)

15 months agoRemove an unnecessary to_string().
Simon Tatham [Sat, 3 Feb 2024 12:08:03 +0000 (12:08 +0000)]
Remove an unnecessary to_string().

Another useful piece of Clippy advice from Ian.

15 months agoFix character counting in masked passwords.
Simon Tatham [Sat, 3 Feb 2024 12:06:04 +0000 (12:06 +0000)]
Fix character counting in masked passwords.

Thanks to Ian for picking this out of Clippy's huge output dump: when
counting the things in a str that EditorCore would regard as
characters, we were using 'map' rather than 'filter' to pick out
things with positive terminal width, which had no effect on the
following .count(). So a Unicode combining character would display an
extra * in the masked password when _not_ editing it, compared to when
editing it.

15 months agoTidy up a few rustfmt divergences.
Simon Tatham [Sat, 3 Feb 2024 11:35:28 +0000 (11:35 +0000)]
Tidy up a few rustfmt divergences.

One of them misaligns Ian's list of test cases (sorry), but it does
have the advantage that I can M-x rust-format-buffer any time I've
made a mess, and not have to think too hard about tidying it up.

15 months agoShow pending follow requests on the Main Menu.
Simon Tatham [Sat, 3 Feb 2024 11:47:59 +0000 (11:47 +0000)]
Show pending follow requests on the Main Menu.

Now you can find out _that_ you have pending requests, in order to go
through the procedure of accepting or rejecting them.

I'm not 100% sure this is the best thing for all users of locked
accounts, so I've left in a TODO item for 'maybe there should be a
method of proactively notifying you of incoming requests'. But this
completes the initial implementation of _something_ that's usable.

15 months agoImplement responding to follow requests.
Simon Tatham [Sat, 3 Feb 2024 11:32:41 +0000 (11:32 +0000)]
Implement responding to follow requests.

If a user has requested to follow you, you get an extra menu item in
the options menu for that user, where you can accept or reject the
request, or leave it unresponded-to for another time.

To make this optional menu item less painful to implement, I made the
MenuKeypressLineGeneral trait also apply to Option<T> for any inner T
that also implements it. So I can do all the routine admin like
ensure_widths without writing three annoying 'if let Some(...)'.

(But that doesn't let me get_value() on an optional CyclingMenuLine -
that would be silly! For retrieving the value, or cycling the line,
you still need to check if it's actually there.)

15 months agoSupport listing your follow requesters.
Simon Tatham [Sat, 3 Feb 2024 10:54:50 +0000 (10:54 +0000)]
Support listing your follow requesters.

We don't yet have a method of approving or denying the request.

15 months agoChange FileType::CAN_LIST into a method.
Simon Tatham [Sat, 3 Feb 2024 10:54:27 +0000 (10:54 +0000)]
Change FileType::CAN_LIST into a method.

Now it can return extra information determined at run time.

15 months agoImprove OtherUserOptionsMenu's handling of follow requests.
Simon Tatham [Sat, 3 Feb 2024 10:40:36 +0000 (10:40 +0000)]
Improve OtherUserOptionsMenu's handling of follow requests.

Now, when the target account is locked, the 'Follow this user' menu
option is reworded as 'Request to follow this user'.

15 months agoFix display of pending follow requests.
Simon Tatham [Sat, 3 Feb 2024 10:27:58 +0000 (10:27 +0000)]
Fix display of pending follow requests.

I had misunderstood the Mastodon docs' description of
Relationship::requested, which said "Do you have a pending follow
request for this user?". It turns out that means _you_ have requested
to follow _them_, not the other way round.

The other way round is also represented in this record, as the
'requested_by' field (mirroring followed and followed_by). Apparently
it's been in the server code for over a year, but accidentally left
out of the documentation until last month.

15 months agoFix keystrokes in options menus.
Simon Tatham [Sat, 3 Feb 2024 09:40:05 +0000 (09:40 +0000)]
Fix keystrokes in options menus.

The status line advertised [RET] as a way to get out of the menu, but
handle_keypress() only supported [Q]. Now it supports [RET] too.

Also, [SPACE] is the keypress to submit changes to user-related
options, but the status line forgot to mention it at all! Now it does.

15 months agologin.rs: factor out ready_to_register().
Simon Tatham [Sat, 3 Feb 2024 09:34:03 +0000 (09:34 +0000)]
login.rs: factor out ready_to_register().

Spotted this obvious duplication in passing, while looking for
something else.

15 months agoTolerate hidden number of followers in Account
Ian Jackson [Fri, 2 Feb 2024 14:45:33 +0000 (14:45 +0000)]
Tolerate hidden number of followers in Account

This can be -1.  Display `(hidden)` when it's not available.

15 months agoMerge Ian's Client refactoring.
Simon Tatham [Fri, 2 Feb 2024 23:17:11 +0000 (23:17 +0000)]
Merge Ian's Client refactoring.

15 months agoTODO: add 'please wait' display update idea.
Simon Tatham [Fri, 2 Feb 2024 23:16:31 +0000 (23:16 +0000)]
TODO: add 'please wait' display update idea.

Ian suggested this, but I'd noticed it too, and just hadn't got round
to either fixing it or (much easier) writing it down.

15 months agoclient: Instrudoce api_request_ok and api_request_raw
Ian Jackson [Fri, 2 Feb 2024 21:07:47 +0000 (21:07 +0000)]
client: Instrudoce api_request_ok and api_request_raw

This avoids open-coded (and easy-to-forget) error handling at each
call site.

Presently, the only caller of api_request_raw is api_request_success,
because the sites that want anything else are open-coding
execute_and_log_request etc.

15 months agoclient: Better handling of JSON deser failures
Ian Jackson [Fri, 2 Feb 2024 15:28:20 +0000 (15:28 +0000)]
client: Better handling of JSON deser failures

If the returned JSON doesn't match the schema implied by our struct,
we now print (a normalised form of) the JSON as part of our error.

If the input isn't JSON at all, we don't include the malformed JSON
text.  It might be hazardous.

15 months agoclient: Introduce api_request_parse and use it in 14 places
Ian Jackson [Fri, 2 Feb 2024 14:19:36 +0000 (14:19 +0000)]
client: Introduce api_request_parse and use it in 14 places

15 months agoUpdate h2 in lockfile
Ian Jackson [Fri, 2 Feb 2024 15:10:52 +0000 (15:10 +0000)]
Update h2 in lockfile

Addresses RUSTSEC-2024-0003.  (May not be relevant, but we should
update out of tidiness.)

    $ nailing-cargo -o audit
    nailing-cargo: out-of-tree, git, building in: `/home/ian/Rustup/Mastodonochrome/Build/mastodonochrome'
    nailing-cargo: using really to run as user `rustcargo'
    nailing-cargo: *WARNING* cwd is not in Cargo.nail thbough it has Cargo.toml!
    nailing-cargo: nailed (0 manifests, 0 packages)
    nailing-cargo: invoking: cargo audit
Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
  Loaded 595 security advisories (from /home/rustcargo/.cargo/advisory-db)
Updating crates.io index
Scanning Cargo.lock for vulnerabilities (257 crate dependencies)
    Crate:     h2
    Version:   0.3.22
    Title:     Resource exhaustion vulnerability in h2 may lead to Denial of Service (DoS)
    Date:      2024-01-17
    ID:        RUSTSEC-2024-0003
    URL:       https://rustsec.org/advisories/RUSTSEC-2024-0003
    Solution:  Upgrade to ^0.3.24 OR >=0.4.2
    Dependency tree:
    h2 0.3.22
    ├── reqwest 0.11.23
    │   └── mastodonochrome 0.1.0
    └── hyper 0.14.28
├── reqwest 0.11.23
└── hyper-tls 0.5.0
    └── reqwest 0.11.23

    error: 1 vulnerability found!

15 months agoCommit Cargo.lock.
Simon Tatham [Fri, 2 Feb 2024 13:01:51 +0000 (13:01 +0000)]
Commit Cargo.lock.

Ian tells me this is supposed to be part of the repository, which I
had not at all understood - I'd assumed it was a local cache. Added,
and un-gitignored.

15 months agoAdd a README and licence document.
Simon Tatham [Fri, 2 Feb 2024 12:33:43 +0000 (12:33 +0000)]
Add a README and licence document.

I was going to delay publishing this repo until I'd polished off the
most important parts of TODO.md, but someone asked me for access, so
I'll change the schedule.

But one thing we _do_ need before publishing is a licence file, so
let's get round to adding that.

15 months agoRemove lib.rs.
Simon Tatham [Thu, 1 Feb 2024 08:03:10 +0000 (08:03 +0000)]
Remove lib.rs.

I'm a bit concerned that with a main.rs and a lib.rs, this package
might accidentally have made both a binary and a library crate,
which (as and when I publish it) might cause people to try to use the
library as if it had a stable and committed API.

In fact all the library modules in this source base are considered
internal to the application, and the interfaces between them are
intended to vary however this application finds convenient. So I
shouldn't accidentally imply otherwise.

15 months agoMove TopLevelError out into its own source file.
Simon Tatham [Thu, 1 Feb 2024 08:06:15 +0000 (08:06 +0000)]
Move TopLevelError out into its own source file.

Now lib.rs is just a list of declarations of other modules, which
seems cleaner.

16 months agoFix Markdown syntax in TODO.md.
Simon Tatham [Wed, 31 Jan 2024 07:42:38 +0000 (07:42 +0000)]
Fix Markdown syntax in TODO.md.

Bullet points don't work unless you separate them from the preceding
paragraph with a blank line.

16 months agoMake [ESC][Y][V] go to the Error Log.
Simon Tatham [Sat, 27 Jan 2024 11:50:26 +0000 (11:50 +0000)]
Make [ESC][Y][V] go to the Error Log.

I put that keypath in the file title, so I shouldn't have forgotten to
make it actually work!

16 months agoNicer handling of 'not found' in bottom-line prompts.
Simon Tatham [Sat, 27 Jan 2024 11:39:39 +0000 (11:39 +0000)]
Nicer handling of 'not found' in bottom-line prompts.

This was another remaining error-handling todo, now tada.

16 months agoReport posting errors in a way that allows retries.
Simon Tatham [Sat, 27 Jan 2024 11:13:17 +0000 (11:13 +0000)]
Report posting errors in a way that allows retries.

Having written that into TODO.md in the previous commit, let's
immediately polish it off, because I already know how to do it - the
login workflow has exactly that kind of error report already.

16 months agoImplement a proper TUI Error Log.
Simon Tatham [Sat, 27 Jan 2024 09:12:14 +0000 (09:12 +0000)]
Implement a proper TUI Error Log.

At last! Now, most errors received from the server will go into a log
that doesn't interrupt and terminate the TUI, and you can at least try
to recover from them and do something else instead.

There's undoubtedly still work to be done in making the errors more
useful, but this is a start. I've left some thoughts in TODO.md.

16 months agoStore a log of errors in the Client.
Simon Tatham [Fri, 26 Jan 2024 08:52:14 +0000 (08:52 +0000)]
Store a log of errors in the Client.

Each entry is a ClientError and a datestamp. But errors generated in
the client don't _automatically_ get added to this log: they get
passed back to the caller of an individual Client method, the same as
they always have. That way the caller can decide whether the error is
one it can handle in some other way, and only if all else fails, call
client.add_to_error_log().

The next plan is for every client.add_to_error_log() to be followed by
throwing the TUI into the Error Log file.

16 months agoGive File an infallible constructor.
Simon Tatham [Fri, 26 Jan 2024 12:53:49 +0000 (12:53 +0000)]
Give File an infallible constructor.

This is useful for data sources whose init() method doesn't actually
need to do anything, because it allows the function constructing one
to statically know that no error will be raised, and not have to write
an ugly unwrap().

16 months agoAdd a text::ErrorLogEntry type to format errors.
Simon Tatham [Fri, 26 Jan 2024 07:40:01 +0000 (07:40 +0000)]
Add a text::ErrorLogEntry type to format errors.

This works towards implementing the TUI Error Log instead of panicking
or terminating with a deliberate error message.

16 months agoTurn FileType::get_from_client into an &self method.
Simon Tatham [Fri, 26 Jan 2024 08:48:04 +0000 (08:48 +0000)]
Turn FileType::get_from_client into an &self method.

This enables the FileType object itself to store information about
where its data comes from, instead of _necessarily_ being constrained
to get it from the client.

Therefore, I've also renamed it, so that the method name doesn't imply
that the data always lives in the client.

This also means that every call to FileContents::update_items() must
pass through the FileType from its owning File, but that's no trouble.

16 months agoMove some ColouredString methods to the right file.
Simon Tatham [Fri, 26 Jan 2024 07:26:33 +0000 (07:26 +0000)]
Move some ColouredString methods to the right file.

Just found these lying around in text.rs, apparently because they were
useful for Paragraph. They should go with the rest of the
ColouredString methods! In particular, is_space() ought to go in the
trait shared between ColouredString{,Slice}, so that there only needs
to be one of it.

16 months agoReorganise the ClientError enum.
Simon Tatham [Thu, 25 Jan 2024 18:09:41 +0000 (18:09 +0000)]
Reorganise the ClientError enum.

Now it has lots more cases, which should make it easier to format each
one nicely into an entry for a TUI-displayed error log.

Other changes:

 - when we keep the error message from the JSON error document, we
   _also_ keep the HTTP status code

 - lots of from_request calls were missing (possibly in the stuff I
   moved in here from the old separate login.rs). Reinstated.

16 months agoJump to new mentions even if we're already in mentions.
Simon Tatham [Thu, 25 Jan 2024 08:56:52 +0000 (08:56 +0000)]
Jump to new mentions even if we're already in mentions.

I noticed this because of the bug fixed in the previous commit - I
_wasn't_ already in my mentions feed, and got thrown into it by an
incoming message, but the file position didn't update.

If the ReadMentions activity state had been properly GCed and
recreated, it would have jumped automatically to the new message. But
it _ought_ to be doing that even if I were in Read Mentions already,
which is a rarer occurrence. So the previous bug gave me the
opportunity to spot and fix this one too, before it hit for real!

16 months agoStop activity states loitering in initial_util.
Simon Tatham [Thu, 25 Jan 2024 08:38:45 +0000 (08:38 +0000)]
Stop activity states loitering in initial_util.

In order to respond to Alt+E by putting a prompt at the bottom of the
current activity (rather than the naïve approach of breaking the
keypress into ESC + E, switching to the utilities menu in response to
the ESC, and then putting the prompt at the bottom of that much less
helpful screen), we remember an activity from the start of the overall
keypress, in the 'initial_util' field of ActivityStack.

But then we _leave_ it there, and don't clean it up - which means it's
returned by ActivityStack::iter(), and hence inhibits garbage
collection of the associated activity state. So a thing could linger
in there for ages despite not actually being on the stack.

16 months agoUse Mastodon's JSON error-documents.
Simon Tatham [Wed, 24 Jan 2024 20:06:44 +0000 (20:06 +0000)]
Use Mastodon's JSON error-documents.

When a Mastodon API request returns an HTTP error status, it generally
also delivers a JSON error-document containing a string. This is a
much better error message than the plain HTTP code, because often it
goes into more useful detail. For example, if you have an auth failure
because you haven't confirmed the email address on your new account
yet, the HTTP error code can't tell you anything about email address
confirmation, but the error-document will. So we'll use those messages
in preference, if they're available.

16 months agoDiscriminate error types in login.
Simon Tatham [Wed, 24 Jan 2024 08:44:59 +0000 (08:44 +0000)]
Discriminate error types in login.

ClientError and ConfigError should be handled differently. The former
suggests you did something wrong in account setup, and you might be
able to recover by doing it again properly (e.g. not misspelling the
server hostname), so we print the error in the TUI and let the user
try again. But the latter probably means you have to sort out your
local account setup (e.g. XDG dirs aren't working, or %APPDATA% isn't
set), and that's more like the kind of fatal error where you quit the
client and fix it externally.

So I've made a new LoginError enum to act as the union of those two
types and also indicate which you have. ConfigError is now passed
back to terminate the TUI completely.

This also means I'm no longer abusing TopLevelError for the union
error type returned by e.g. confirm_registration_fallible. That was
bad in its own way because it prefixed 'mastodonochrome: error:' to
the error description as if it were reporting on the terminal.

16 months agoMove saving of auth file into auth.rs.
Simon Tatham [Wed, 24 Jan 2024 20:04:34 +0000 (20:04 +0000)]
Move saving of auth file into auth.rs.

Makes more sense there, right next to AuthConfig::load. And we were
doing it twice, so it needs to move _somewhere_ central.

16 months agoChange the message for AuthError::Nonexistent.
Simon Tatham [Wed, 24 Jan 2024 08:48:11 +0000 (08:48 +0000)]
Change the message for AuthError::Nonexistent.

"Not logged in" used to be correct, when we didn't support account
registration. But now the auth file can _exist_ while still being
logged in. So we should be more precise in the translation of this
error code: it really means <cfgdir>/auth is absent in an ENOENT sort
of way.

However, we shouldn't normally _see_ that message: it's one of the few
error cases that we detect programmatically and divert into a handler
for (to wit, the login flow).

16 months agoAnother run of 'cargo fmt'.
Simon Tatham [Wed, 24 Jan 2024 20:02:30 +0000 (20:02 +0000)]
Another run of 'cargo fmt'.

Sooner or later I'm going to have to start automating this. Otherwise
there will be too many random formatting changes mixed in to every
other patch I make.

16 months agoChange my mind again about composing.
Simon Tatham [Sun, 21 Jan 2024 15:36:35 +0000 (15:36 +0000)]
Change my mind again about composing.

Composition activities should stack above reading files, but below
things to which you might pop out to get more information (such as
checking the username of someone to @mention). So I've given them an
Activity category of their own, which has at most one occupant (like
UtilityActivity) but is separate and just below Utility.

I'm still not sure this is right, but I think it's better than before.
I'll try using it for a while and see.

16 months agoRethink utility status of some activities.
Simon Tatham [Sun, 21 Jan 2024 13:26:52 +0000 (13:26 +0000)]
Rethink utility status of some activities.

ComposeToplevel and ComposeReply are very similar in this environment,
so I think it's wrong that one should be a utility activity and the
other not. The current status mimics real Monochrome, with
ComposeToplevel and ComposeReply corresponding to adding to a file and
sending a message to a user respectively; but in real Mono, those two
activities are much more different from each other than they are here,
so I don't think the same rule should apply.

Conversely, I'm promoting ThreadFile to a _non_-utility activity, on
the basis that all activities involving viewing a file of actual toots
ought to have the same status, or else it's confusing. In particular,
it's annoying to try to examine a user seen in someone's thread, and
then find you can't easily come back to the place you were at in the
thread itself.

16 months agoPrettify username and email in account registration.
Simon Tatham [Sun, 21 Jan 2024 11:27:49 +0000 (11:27 +0000)]
Prettify username and email in account registration.

The username is now shown with its domain suffix, but doesn't make you
type that suffix. And the email is validated for basic syntax.

16 months agoKeep persistent ActivityStates for everything on the stack.
Simon Tatham [Sun, 21 Jan 2024 07:02:59 +0000 (07:02 +0000)]
Keep persistent ActivityStates for everything on the stack.

This fixes the cases where temporarily going to another full-screen
activity failed to restore the in-progress state of the previous one.
In particular, nipping out to the utilities menu from composing a
post, and reading the server rules during account registration.

It's a shame; I'd have preferred to be deleting and recreating state
objects all the time, to ensure they had a well-defined amount of
internal state. But this needed less organisation. Perhaps I can come
back and do it better another time.

16 months agoFix failure to update fave/boost flags on boosts.
Simon Tatham [Sat, 20 Jan 2024 15:34:58 +0000 (15:34 +0000)]
Fix failure to update fave/boost flags on boosts.

When you faved/unfaved or boosted/unboosted a status that you yourself
saw via a boost, the actual operation was happening successfully, and
the updated version of the _boosted_ status was going into our
Client's cache - but re-retrieving the _boost itself_ didn't include
the updated copy of the contained original post.

16 months agoRerun 'cargo fmt'.
Simon Tatham [Sat, 20 Jan 2024 14:56:27 +0000 (14:56 +0000)]
Rerun 'cargo fmt'.

16 months agoSupport registering a new account via this client.
Simon Tatham [Fri, 19 Jan 2024 08:05:03 +0000 (08:05 +0000)]
Support registering a new account via this client.

This is provided as a second workflow on the TUI login page. You get
to enter a username, email address and password, and register your
account. You still have to respond to an email sent by the
server (just as much as logging in, it needs to know that you're
really the owner of that email address); this can be done by clicking
the link in the message, or pasting it into the login workflow,
whichever you think is easiest.

Clicking the link has weird effects if you set a redirect_uri of
"urn:ietf:wg:oauth:2.0:oob": the Mastodon web server actually tries to
redirect your browser to that URI, which causes at least Firefox to
prompt for an application to open it in, which is thoroughly confusing
and looks more like an error message than the indication of success it
actually is. So instead I've made it redirect to a page on my web
site, which is still a bit odd, but less odd than that.

16 months agoGeneralise EditableMenuLine's data update.
Simon Tatham [Sat, 20 Jan 2024 11:46:22 +0000 (11:46 +0000)]
Generalise EditableMenuLine's data update.

This allows the Data parameter type to bake in extra information which
is not affected by the editor providing it with new text. The idea is
to allow one password editor field to know about the password in the
other field, so as to display differently if they don't match.

16 months agoAdd SingleLineEditor feature to mask passwords.
Simon Tatham [Sat, 20 Jan 2024 10:22:09 +0000 (10:22 +0000)]
Add SingleLineEditor feature to mask passwords.

The implementor of an EditableMenuLineData trait can now set the trait
constant SECRET to indicate that the editor should display the text
as ******* while editing. However, the trait is responsible for doing
the same masking itself when displaying the data in non-editing
mode.

(This division of labour is necessary so that display() can also apply
other display features, such as complaining that you haven't given a
password at all yet, or that they don't match. display() is the only
thing that can know _which_ of its output needs masking.)

16 months agoActivity to view the instance rules.
Simon Tatham [Fri, 19 Jan 2024 08:52:30 +0000 (08:52 +0000)]
Activity to view the instance rules.

This isn't used by anything yet, but it will be, when I implement
account registration directly from the client.

16 months agoAlign [^X] in menus left instead of right.
Simon Tatham [Fri, 19 Jan 2024 13:24:12 +0000 (13:24 +0000)]
Align [^X] in menus left instead of right.

That way the actual letter lines up under other letters.

16 months agoRewrite the login step as part of the TUI.
Simon Tatham [Thu, 18 Jan 2024 09:01:30 +0000 (09:01 +0000)]
Rewrite the login step as part of the TUI.

Now it's reasonably user-friendly, and once you've logged in, you can
transition straight to actually using the client.

Also, this menu is a good place to put a 'register as new user'
alternative option.

16 months agoConditionalise a lot of the utilities menu
Simon Tatham [Thu, 18 Jan 2024 12:56:16 +0000 (12:56 +0000)]
Conditionalise a lot of the utilities menu

16 months agoAdd centring as an option to Paragraph.
Simon Tatham [Fri, 19 Jan 2024 06:14:06 +0000 (06:14 +0000)]
Add centring as an option to Paragraph.

16 months agoMake MainMenu explicit at the top of the activity stack.
Simon Tatham [Thu, 18 Jan 2024 08:55:54 +0000 (08:55 +0000)]
Make MainMenu explicit at the top of the activity stack.

This will allow me to replace it with a different top-level activity
when we're in TUI login mode.

16 months agoRefactor login so that Client does it all.
Simon Tatham [Wed, 17 Jan 2024 13:08:48 +0000 (13:08 +0000)]
Refactor login so that Client does it all.

This sets up to allow login to happen within a Tui context, and also,
transfer seamlessly into a logged-in session once you've finished it.

16 months agoStop centrally prepending /api to URLs.
Simon Tatham [Wed, 17 Jan 2024 12:46:16 +0000 (12:46 +0000)]
Stop centrally prepending /api to URLs.

If I move the login logic into client.rs, then we'll need a few URLs
that start with /oauth instead of /api.

16 months agoMake everything in AuthConfig optional.
Simon Tatham [Wed, 17 Jan 2024 12:42:52 +0000 (12:42 +0000)]
Make everything in AuthConfig optional.

16 months agoRemove unneeded Auth::fqaccount() method.
Simon Tatham [Wed, 17 Jan 2024 12:34:12 +0000 (12:34 +0000)]
Remove unneeded Auth::fqaccount() method.

I never ended up using it, preferring Client::our_account_fq().

16 months agoRun through rustfmt.
Simon Tatham [Wed, 17 Jan 2024 07:41:53 +0000 (07:41 +0000)]
Run through rustfmt.

If this is a widespread standard, I might as well start getting used
to it.

16 months agoMore TODO updates.
Simon Tatham [Mon, 15 Jan 2024 19:35:13 +0000 (19:35 +0000)]
More TODO updates.

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.