First let me say that this is essentially a restatement of the answer linked in your question.
I suggest that you use symmetric key encryption to guard files and asymmetric (public) key encryption to guard the symmetric encryption keys. You could use an existing PGP/GPG key pair, or, to make this transparent, generate a key pair explicitly for your application. If you do the latter, please use tried and tested code to generate the keys.
You stated a requirement that no keys be stored on the server because " I don't want to give the service's maintainer the ability to access user's data." As long as keys stored on the server are encrypted, the service's maintainer has no access to the data, so I've interpreted "no keys on the server" as "no keys which would allow access to the data."
The process works like this: When a file is uploaded, it must be encrypted (by an app on the sender's client) using a symmetric algorithm like AES and a randomly-generated key. The key must be generated by a cryptographically secure random number generator (CSPRNG)
The encrypted file is uploaded to the server. The symmetric key, encrypted with the sender's public key is uploaded as file metadata, associated with the sender's ID. If a file is uploaded by a user with the ID [email protected], the metadata would look like:
[email protected] | encrypted (with KA) symmetric key
At this point, only Alice can read the file because only Alice has the private key that will decrypt the file's encrypted symmetric key. (The application must have discarded the unencrypted copy of the symmetric key soon after the metadata were updated.)
If Alice wants to allow [email protected] to retrieve the file, she adds to the metadata a line like this:
[email protected] | encrypted (with KB) symmetric key
Alice does that by retrieving her own metadata, decrypting the symmetric key with her private key, and re-encrypting with Bill's public key.
Assuming the metadata file itself is unprotected, Bill can pass access to Charlie by performing the same kind of operation. That is not only OK, it is good. Bill can obviously download the file and give a copy to whomever he pleases. If access is passed through the file's metadata, then there's a record of what happened. (Bill can still pass the file to others, but is no longer forced to take that route.)
Because of your requirement that only one password be used, you'll need to use the password that unlocks the private key as a login password. One way to do that might be to store on the server an authenticator for each user, encrypted with the user's public key. Only a user with the corresponding private key can decrypt it and return the plain-text authenticator to the server.
Everything up to the login involves end-to-end encryption, and so everything passing "over the wire" is encrypted. For the login authentication, the client must return the plain text authenticator, and that means a TLS connection is needed.