Skip to content

Instantly share code, notes, and snippets.

@imdwit

imdwit/Background.elm Secret

Created Aug 24, 2019
Embed
What would you like to do?
port module Background exposing (init, main, subscriptions, update)
import Data.Asset as Asset
import Data.Project as Proj exposing (Project)
import Data.User as User
import Data.Utils as Utils
import Dict exposing (Dict)
import Extension.PopUp as PopUp
import Json.Decode as Decode
import Json.Decode.Pipeline as JDP
import Json.Encode as E exposing (Value)
import Platform
import RemoteData
import Request.SignedUrl as SignedUrl
port broadcast : Value -> Cmd msg
port fromExt : (Value -> msg) -> Sub msg
port extOut : Value -> Cmd msg
extOutBound =
extOut << outEncoder
type ExtOutBound
= FetchProjectsByHostName String
| InjectContentScripts String
| UploadAsset Asset.Preview String
| SeedAssets_ (List Asset.Preview)
outEncoder out =
E.object <|
case out of
FetchProjectsByHostName hostname ->
[ ( "tag", E.string "fetchProjectsByHostName" )
, ( "payload", E.string hostname )
]
InjectContentScripts projectId ->
[ ( "tag", E.string "injectContentScripts" )
, ( "payload", E.string projectId )
]
UploadAsset preview url ->
[ ( "tag", E.string "signedUrlResponse" )
, ( "payload"
, E.object
[ ( "asset", Asset.preivewEncoder preview )
, ( "url", E.string url )
]
)
]
SeedAssets_ previews ->
[ ( "tag", E.string "seedAssets" )
, ( "payload"
, E.list Asset.preivewEncoder previews
)
]
fetchProjectsByHostName hostname =
extOutBound <| FetchProjectsByHostName hostname
injectContentScripts : String -> Cmd msg
injectContentScripts projectId =
-- @TODO GROSS
extOutBound <| InjectContentScripts projectId
signedUrlResponse preview url =
extOutBound <| UploadAsset preview url
seedAssets : Dict String Asset.Preview -> Cmd msg
seedAssets staging =
extOutBound <| SeedAssets_ <| List.map Tuple.second <| Dict.toList staging
type alias Model =
{ popUp : PopUp.Model
, hostname : String
, projects : List Project
, staging : Dict String Asset.Preview
}
initialModel : Model
initialModel =
{ popUp = PopUp.initialModel
, hostname = ""
, projects = []
, staging = Dict.empty
}
encodeInitialPopup =
PopUp.encoder initialModel.popUp
init : Value -> ( Model, Cmd Msg )
init flags =
( initialModel
, broadcast ( encodeInitialPopup)
)
type Msg
= NoOp
| SyncPopup PopUp.Model
| SetHostname String
| SetProjects (List Project)
| AddFileToStaging Asset.Preview
| UnstageFile String
| GetSignedUrl String
| GetSignedUrlResponse Asset.Preview (RemoteData.WebData String)
| SeedAssets
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
SyncPopup popUp ->
let
model_ =
{ model | popUp = popUp }
cmd_ =
case ( popUp.auth, model.projects ) of
( User.Anonymous, _ ) ->
Cmd.none
( User.Authed _, [] ) ->
fetchProjectsByHostName model.hostname
( User.Authed _, _ ) ->
Cmd.none
in
( model_, Cmd.batch [ broadcast <| PopUp.encoder popUp, cmd_ ] )
SetHostname hostname ->
let
cmd =
case model.popUp.auth of
User.Anonymous ->
Cmd.none
User.Authed _ ->
fetchProjectsByHostName model.hostname
in
( { model | hostname = hostname }, cmd )
SetProjects projects ->
case projects of
[] ->
( model, Cmd.none )
proj :: projs ->
let
popup =
model.popUp
popup_ =
{ popup
| hostnames = List.map .hostname projects
}
in
( { model | projects = projects }
, Cmd.batch
[ injectContentScripts (Proj.getProjectId proj)
, Utils.delay 100 SeedAssets
, Utils.delay 100 (SyncPopup popup_)
]
)
SeedAssets ->
( model, seedAssets model.staging )
AddFileToStaging preview ->
( { model | staging = Dict.insert preview.publicId preview model.staging }, Cmd.none )
UnstageFile publicId ->
( { model | staging = Dict.remove publicId model.staging }, Cmd.none )
GetSignedUrl publicId ->
case model.popUp.auth of
User.Authed auth ->
let
currentUserId =
auth.currentUser.id
accessToken =
auth.accessToken
preview =
Dict.get publicId model.staging
getSignedUrl prev proj =
SignedUrl.getSignedUrl currentUserId accessToken proj.teamId prev
|> RemoteData.sendRequest
|> Cmd.map (GetSignedUrlResponse prev)
fetch =
model.projects
|> List.head
|> Maybe.map2 getSignedUrl preview
|> Maybe.withDefault Cmd.none
in
( model, fetch )
User.Anonymous ->
( model, Cmd.none )
GetSignedUrlResponse preview (RemoteData.Success url) ->
( model, signedUrlResponse preview url )
GetSignedUrlResponse _ _ ->
-- @TODO error handling
( model, Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions model =
extInBound ()
extInBound : a -> Sub Msg
extInBound _ =
fromExt <|
\value ->
case Decode.decodeValue decoder value of
Ok (SyncPopup popupModel) ->
SyncPopup popupModel
Ok (SetHostname hostname) ->
SetHostname hostname
Ok (SetProjects projs) ->
SetProjects projs
Ok (AddFileToStaging preview) ->
AddFileToStaging preview
Ok (UnstageFile publicId) ->
UnstageFile publicId
Ok (GetSignedUrl p) ->
GetSignedUrl p
Ok (GetSignedUrlResponse _ _) ->
NoOp
Ok SeedAssets ->
NoOp
Ok NoOp ->
NoOp
Err err ->
-- let
-- _ =
-- Debug.log "extinboudn error" err
-- in
NoOp
decoder =
Decode.field "tag" Decode.string
|> Decode.andThen
(\tag ->
case tag of
"syncPopup" ->
Decode.succeed SyncPopup
|> JDP.required "popup" PopUp.decoder
"setHostname" ->
Decode.succeed SetHostname
|> JDP.required "payload" Decode.string
"setProjects" ->
Decode.succeed SetProjects
|> JDP.required "payload" (Decode.list Proj.decodeProject)
"addFileToStaging" ->
Decode.succeed AddFileToStaging
|> JDP.required "payload" Asset.decodePreview
"unstage" ->
Decode.succeed UnstageFile
|> JDP.required "payload" Decode.string
"upload" ->
Decode.succeed GetSignedUrl
|> JDP.required "payload" Decode.string
"uploadComplete" ->
Decode.succeed UnstageFile
|> JDP.required "payload" Decode.string
_ ->
Decode.fail "woops"
)
main =
Platform.worker
{ init = init
, update = update
, subscriptions = subscriptions
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.