cabal-client icon indicating copy to clipboard operation
cabal-client copied to clipboard

implement file sending

Open cblgh opened this issue 6 years ago • 6 comments

see cabal-client-files for @nikolaiwarner initial implementation

  • keep track of files sent per per, allow querying
  • index by file type, file name

images

mostly ux ideas

  • allow sending many images at once
  • ability to group images into an album (i.e. all 15 files i dragged at the same time should be marked as a group somehow) signal on mobile has a nice ux for for this, also mastodon too
  • ability to add alt text. any peer should be able to reference an image and add alt text for vision impaired, spreading out the burden of helping others. see the topic view for one way of implementing this
  • erase exif data by default (add override boolean)

cblgh avatar Sep 14 '19 16:09 cblgh

maybe, in a future version, we could integrate with cobox to handle everything filesharing https://github.com/coboxcoop :o

cblgh avatar Sep 17 '19 06:09 cblgh

If I may suggest an architecture: consider a cabal message type, chat/file of this form:

{
  type: 'chat/file',
  content: {
    text: 'whatever the user wants to say',
    channel: 'some channel name. if it didnt exist before, it does now!',
    link: 'hyper://{hyperdrive-discoverykey}/{path}',
    content_type: '{mime-type, ex: image/gif}'
  }
}

This type works like a normal chat message, but is annotated to link to a hyperdrive that contains the file. In this way, the feed does not contain the file itself so that clients must opt-in to media storage, and the message may link to a drive containing many files. This allows messages that contain file links to be indexed by the client without opting in to media storage, and gives enough evidence that clients can produce previews based on the file's content type.

As a usage example: an application might use cabal-client to optimistically download gifs, jpegs, and other image types in order to create previews, or a linked HTML file might be parsed for its <title>, but other data types are previewed pessimistically by displaying only the link and the expected content type.

Imagine this API:

  • CabalDetails.publishFile(filePathOrLink, msg, opts, cb): Uses the filepath to retrieve a file and create a hyperdrive containing it at its same filename (ex: ~/Music/crow_sounds.wav becomes hyper://{key}/crow_sounds.wav), and then updating the content.link property with the appropriate link. If the parameter is already a hyper:// link, the client connects to its swarm and downloads the linked file.
  • CabalDetails.getStoredFiles([channel], cb): Returns a list of all chat/file messages whose hyperdrives are currently being peered as well as the hyperdrive itself, optionally for a specific channel. Defaults to all channels. Ex cb: (err, [{ message, hyperdrive }]) => { ... }
  • Client.getMessages(...): Document optional type property to opts, which can then be set to a string like chat/text or chat/files. (This doesn't actually require a code change.)
  • Client.searchFiles(searchString, opts, cb, cabal = this.currentCabal): Like searchMessages but checks against the content.link property.
  • ChannelDetails.getPage(...): Add optional type property to opts, which can then be set to a string like chat/text or chat/files. Messages that do not have the given type are discarded.

Multiple hyperdrives can be managed using a hyperdrive-daemon-client which connects to a hyperdrive-daemon which actually peers the hyperdrives. Alternatively, cabal-client can manage its own hyperdrives using an API like multifeed or multi-hyperdrive as hyperdrive-daemon-client currently only supports a subset of hyperdrive methods.

garbados avatar Jun 30 '20 19:06 garbados

@garbados I agree that opt-in is the easiest way to implement this (auto-seeding has big questions around it), and offloading the work to an existing p2p file sharing system like hyperdrive makes sense.

This approach is also nice because, by being opt-in, it sidesteps abuse vectors, since you can't make other peers perform big downloads or join other swarms. I imagine cabal-client managing a set of hyperdrive swarms and files within them: some to seed, others to just download and then leave.

Here are my thoughts on what a blob API for clients could look like:

createBlobWriteStream(readableStream, cb)

streams the blob directly into hypedrive's createWriteStream, and cb is called with a hyper:// link.

requestBlob(link, opts, cb)

marks link (a hyper:// url) as wanted, and adds it to the background hyperdrive swarms. cb could be called when it's been added to the queue. We could expose opts.seed to indicate whether to keep seeding the hyperdrive after downloading.

onBlobReady(link, cb)

fires once the blob has been downloaded, or on next tick if already downloaded.

createBlobReadStream(link)

read the blob's data. If not yet downloaded, the stream waits until it is. (We could have an opts.wait like hypercore to avoid blocking forever).

seedBlob(link, cb), unseedBlob(link, cb)

(un)seed a file in a hyperdive

hackergrrl avatar Jul 02 '20 06:07 hackergrrl

recently i've also become more interested in the possibility of ephemeral file exchange (i.e. not having any memory of who sent what)

(p.s. great posts nettle & garbados!! :3)

cblgh avatar Jul 02 '20 07:07 cblgh

@cblgh definitely both useful!!

okdistribute avatar Jul 02 '20 16:07 okdistribute

Support uploading display jpeg、png、mp4、ogg、not generate URL link

Pantyhose-X avatar Oct 15 '22 06:10 Pantyhose-X