// License: LGPL-3.0-or-later // npm const R = require('ramda') const serialize = require('form-serialize') const flyd = require('flyd') const mergeAll = require('flyd/module/mergeall') const filter = require('flyd/module/filter') const keepWhen = require('flyd/module/keepwhen') const takeUntil = require('flyd/module/takeuntil') const sampleOn = require('flyd/module/sampleon') const zip = require('flyd-zip') const url$ = require('flyd-url') const snabbdom = require('snabbdom') const h = require('snabbdom/h') const render = require('ff-core/render') const validated = require('ff-core/validated-form') const notification = require('ff-core/notification') const flatMap = R.curry(require('flyd/module/flatmap')) // common const request = require('../../../../../common/request') const googz = require('../../../../../common/google-api') // from gmail dir const format = require('./format') var constraints = { to: {email: true, required: true} , cc: {email: true} , bcc: {email: true} , subject: {required: true} , body: {required: true} } function init(parentState) { var state = {} const isSignedInOnLoad$ = googz.init('https://mail.google.com/') state.newSignIn$ = flyd.stream() const signInClick$ = R.compose( filter(R.not) , sampleOn(R.__, isSignedInOnLoad$) )(parentState.clickComposing$) const isSignedInWithClick$ = flatMap(googz.signIn, flyd.merge(state.newSignIn$, signInClick$)) const isSignedIn$ = flyd.merge(isSignedInOnLoad$, isSignedInWithClick$) flyd.map(loadGmailApi, isSignedIn$) state.from$ = R.compose( flatMap(googz.email) , filter(Boolean) )(isSignedIn$) const threadData$ = flatMap(getThreadData, parentState.threadId$) state.formattedThreadData$ = flyd.map(format.thread, threadData$) state.composeForm = validated.init({constraints}) state.replyForm = validated.init({constraints: {body: {required: true}}}) const formattedComposeData$ = flyd.map(format.composeData, state.composeForm.validData$) const formattedReplyData$ = flyd.map(format.replyData, state.replyForm.validData$) const sendData$ = flyd.merge(formattedReplyData$, formattedComposeData$) state.sendResponse$ = flatMap(send, sendData$) const formattedSaveData$ = flyd.map(R.apply(format.saveData), zip([state.sendResponse$, state.composeForm.validData$])) state.saveResult$ = flatMap(save, formattedSaveData$) const afterCompose$ = sampleOn(state.sendResponse$, state.composeForm.submit$) const afterReply$ = sampleOn(state.sendResponse$, state.replyForm.submit$) flyd.map(_ => state.composeForm.submit$().reset(), afterCompose$) flyd.map(_ => state.replyForm.submit$().reset(), afterReply$) return state } const send = data => { const result$ = flyd.stream() gapi.client.gmail.users.messages.send(data).execute(result$) return result$ } const loadGmailApi = _ => { if(gapi.client.gmail) return gapi.client.load('gmail', 'v1') } const save = data => { const path = `/nonprofits/${app.nonprofit_id}/supporter_emails/gmail` var send = {gmail: data} return flyd.map(req => req.body, request({method: 'post', path, send}).load) } const getThreadData = id => { const result$ = flyd.stream() gapi.client.gmail.users.threads.get({ 'userId': 'me' , 'id': id }).execute(result$) return result$ } module.exports = {init}