# Phoenix Live View Dropzone

A file upload solution for Phoenix Live View.

## Use case

When you wish to upload file(s) in the background of your Live View to a pre authenticated resource.

This can be a route within your Phoenix app, or it can be to a 3rd party store such as S3. \
This implementation was developed against an application that provided S3 signed urls for uploads.

## Usage

Use the provided `PhoenixLiveViewDropzone` stateless Live Component for integration into your view.


  <%= live_component @socket, PhoenixLiveViewDropzone, file_data: @file_data %>

Where `@file_data` is expected to be a map `%{id: id, url: url}` which can be blank by default.

When a file is uploaded the view will emit `phx-dropzone` events via live view in the following structure:

[event_name, event_payload]

e.g. `handle_event/3` would be implemented as:

def handle_event("phx-dropzone", [_event, _payload], socket) do
  {:noreply, socket}

There are two events currently supported:

1) `generate-url`

Is issued on the file first being selected to generate a url to upload to. The payload is:

%{"id" => "string-id-for-file", "name" => "string-filename-on-disk" }

To respond to this you are expected to assign `file_data` to `%{id: id, url: your_url}`. \
You need to do this only long enough for the updated hook to fire and uploading to begin.

2) `file-status`

Is issued as the file is uploaded, and on completion. The payload id:

  "id" => "string-id-for-file",        # the files id
  "name" => "string-filename-on-disk", # the files name
  "progress" => 42,                    # as a percentage
  "sent" => 42,                        # as a number of bytes sent
  "size" => 100,                       # size of file in bytes
  "status" => "string"                 # one of inProgress, Done, Error

### Options

  The following assigns can be set to customise various attributes:

  * `dom_id` - string - Sets the id attribute on the outer div, defaults to `phoenix-live-view-dropzone`.
  * `css_class` - string - Sets the class attribute on the outer div, defaults to `phoenix-live-view-dropzone`.
  * `hook_name` - string - Sets the `phx-hook` value on the outer div, defaults to `PhoenixLiveViewDropzone`.
  * `button_text` - string - Sets the text of the button in the drop zone.
  * `file_types` - string or list of strings - Sets the mime types the file picker will allow.
  * `target` - string - Sets the phx-target value for events.
  * `text` - string - Sets text that will be displayed above the button in the dropzone.

## Installation

This package assumes you have a working Live View setup. Follow the instructions for setting up live view first.

Then the package can be installed by adding `phoenix_live_view_dropzone` to your list of dependencies in `mix.exs`:

def deps do
    {:phoenix_live_view_dropzone, "~> 0.0.7"}

You then need to wire up the package dependency, in your package.json add:

  "phoenix_live_view_drop_zone": "file:../deps/phoenix_live_view_dropzone"

And connect the hook.

import { PhoenixLiveViewDropzone } from "phoenix_live_view_drop_zone";

let Hooks = {};
Hooks.PhoenixLiveViewDropzone = new PhoenixLiveViewDropzone();

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}});