Skip to content
This repository was archived by the owner on Sep 22, 2021. It is now read-only.

Commit

Permalink
Crawl important and primary inboxes from the dom rather than trying t…
Browse files Browse the repository at this point in the history
…o figure it from the labels #411
  • Loading branch information
Thomas101 committed Oct 31, 2016
1 parent 7e39af3 commit 3c4903f
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 28 deletions.
32 changes: 25 additions & 7 deletions src/scenes/mailboxes/src/Components/WebView.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const React = require('react')
const ReactDOM = require('react-dom')
const camelCase = require('camelcase')

const SEND_RESPOND_PREFIX = '__SEND_RESPOND__'
const WEBVIEW_EVENTS = [
'load-commit',
'did-finish-load',
Expand Down Expand Up @@ -112,10 +113,11 @@ module.exports = React.createClass({
* @return true if the event was handled in the siphon
*/
siphonIPCMessage (evt) {
if (evt.channel.type === 'respond-process-memory-info') {
if (this.ipcPromises[evt.channel.id]) {
this.ipcPromises[evt.channel.id](evt.channel.data)
delete this.ipcPromises[evt.channel.id]
if (evt.channel.type.indexOf(SEND_RESPOND_PREFIX) === 0) {
if (this.ipcPromises[evt.channel.type]) {
clearTimeout(this.ipcPromises[evt.channel.type].timeout)
this.ipcPromises[evt.channel.type].resolve(evt.channel.data)
delete this.ipcPromises[evt.channel.type]
}
return true
} else if (evt.channel.type === 'elevated-log') {
Expand Down Expand Up @@ -181,10 +183,26 @@ module.exports = React.createClass({
* @return promise
*/
getProcessMemoryInfo () {
return new Promise((resolve) => {
return this.sendWithResponse('get-process-memory-info')
},

/**
* Calls into the webview to get some data
* @param sendName: the name to send to the webview
* @param obj={}: the object to send into the webview. Note __respond__ is reserved
* @param timeout=5000: the timeout before rejection
* @return promise
*/
sendWithResponse (sendName, obj = {}, timeout = 5000) {
return new Promise((resolve, reject) => {
const id = Math.random().toString()
this.ipcPromises[id] = resolve
this.getWebviewNode().send('get-process-memory-info', { id: id })
const respondName = SEND_RESPOND_PREFIX + ':' + sendName + ':' + id
const rejectTimeout = setTimeout(() => {
delete this.ipcPromises[respondName]
reject({ timeout: true })
}, timeout)
this.ipcPromises[respondName] = { resolve: resolve, timeout: rejectTimeout }
this.getWebviewNode().send(sendName, Object.assign({}, obj, { __respond__: respondName }))
})
},

Expand Down
63 changes: 61 additions & 2 deletions src/scenes/mailboxes/src/Dispatch/mailboxDispatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,72 @@ class MailboxDispatch {
* Makes a fetch to a set of responders
* @param name: the name of the responder to call
* @param args=undefined: arguments to pass to the responders
* @param timeout=undefined: set to a ms to provide a timeout
* @return promise
*/
request (name, args = undefined) {
request (name, args = undefined, timeout = undefined) {
if (!this.__responders__[name] || this.__responders__[name].length === 0) {
return Promise.resolve([])
}
return Promise.all(this.__responders__[name].map((fn) => fn(args)))

const requestPromise = Promise.all(this.__responders__[name].map((fn) => fn(args)))
if (timeout === undefined) {
return requestPromise
} else {
return Promise.race([
requestPromise,
new Promise((resolve, reject) => {
setTimeout(() => reject({ timeout: true }), timeout)
})
])
}
}

/* **************************************************************************/
// Responders : Higher level
/* **************************************************************************/

/**
* Fetches the process memory info for all webviews
* @return promise with the array of infos
*/
fetchProcessMemoryInfo () {
return this.request('fetch-process-memory-info')
}

/**
* Fetches the gmail unread count
* @param mailboxId: the id of the mailbox
* @return promise with the unread count or undefined
*/
fetchGmailUnreadCount (mailboxId) {
return this.request('get-gmail-unread-count:' + mailboxId, {}, 1000)
.then((responses) => {
return Promise.resolve((responses[0] || {}).count)
})
}

/**
* Fetches the gmail unread count and retries on timeout
* @param mailboxId: the id of the mailbox
* @param maxRetries=30: the number of retries to attempt. A second between each
* @return promise with the unread count or undefined
*/
fetchGmailUnreadCountWithRetry (mailboxId, maxRetries = 30) {
return new Promise((resolve, reject) => {
const tryFetch = (tries) => {
this.fetchGmailUnreadCount(mailboxId).then(
(res) => resolve(res),
(err) => {
if (err.timeout && tries < maxRetries) {
setTimeout(() => tryFetch(tries + 1), 1000)
} else {
reject(err)
}
})
}
tryFetch(0)
})
}

/* **************************************************************************/
Expand Down
38 changes: 32 additions & 6 deletions src/scenes/mailboxes/src/stores/google/googleActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ const credentials = require('shared/credentials')
const googleHTTP = require('./googleHTTP')
const mailboxStore = require('../mailbox/mailboxStore')
const mailboxActions = require('../mailbox/mailboxActions')
const Mailbox = require('shared/Models/Mailbox/Mailbox')
const {Mailbox, Google} = require('shared/Models/Mailbox')
const {ipcRenderer} = window.nativeRequire('electron')
const reporter = require('../../reporter')
const {mailboxDispatch} = require('../../Dispatch')

const cachedAuths = new Map()

Expand Down Expand Up @@ -245,18 +246,43 @@ class GoogleActions {
syncMailboxUnreadCount (mailboxId, forceFullSync = false) {
const { auth } = this.getAPIAuth(mailboxId)

const mailbox = mailboxStore.getState().getMailbox(mailboxId)
const label = mailbox.google.unreadLabel
const unreadMode = mailbox.google.unreadMode

const promise = Promise.resolve()
.then(() => {
// Step 1. Counts: Fetch the mailbox label
const mailbox = mailboxStore.getState().getMailbox(mailboxId)
const label = mailbox.google.unreadLabel
return Promise.resolve()
.then(() => googleHTTP.fetchMailboxLabel(auth, label))
.then(() => {
// Step 1.1: call out to google
return googleHTTP.fetchMailboxLabel(auth, label)
})
.then(({ response }) => {
// Step 2.2: Some mailbox types need to update the response by what's in the UI
if (unreadMode === Google.UNREAD_MODES.PRIMARY_INBOX_UNREAD || unreadMode === Google.UNREAD_MODES.INBOX_UNREAD_IMPORTANT) {
return Promise.resolve()
.then(() => mailboxDispatch.fetchGmailUnreadCountWithRetry(mailboxId, forceFullSync ? 30 : 5))
.then((count) => {
if (count === undefined) {
return response
} else {
return Object.assign(response, {
threadsUnread: count,
artificalThreadsUnread: true
})
}
})
} else {
return response
}
})
.then((response) => {
// Step 1.3: Update the models. Decide if we changed
const mailbox = mailboxStore.getState().getMailbox(mailboxId)
mailboxActions.setGoogleLabelInfo(mailboxId, response.response)
mailboxActions.setGoogleLabelInfo(mailboxId, response)
return Promise.resolve({
changed: forceFullSync || mailbox.messagesTotal !== response.response.messagesTotal
changed: forceFullSync || mailbox.messagesTotal !== response.messagesTotal
})
})
})
Expand Down
36 changes: 26 additions & 10 deletions src/scenes/mailboxes/src/ui/Mailbox/GoogleMailboxWindow.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ module.exports = React.createClass({
},

componentDidMount () {
this.gmailCountPromises = {}

// Stores
flux.mailbox.S.listen(this.mailboxesChanged)
flux.settings.S.listen(this.settingsChanged)
Expand All @@ -43,6 +45,7 @@ module.exports = React.createClass({
mailboxDispatch.on('reload', this.handleReload)
mailboxDispatch.on('openMessage', this.handleOpenMessage)
mailboxDispatch.respond('fetch-process-memory-info', this.handleFetchProcessMemoryInfo)
mailboxDispatch.respond('get-gmail-unread-count:' + this.props.mailboxId, this.handleGetGmailUnreadCount)
ipcRenderer.on('mailbox-window-find-start', this.handleIPCSearchStart)
ipcRenderer.on('mailbox-window-find-next', this.handleIPCSearchNext)
ipcRenderer.on('mailbox-window-navigate-back', this.handleIPCNavigateBack)
Expand All @@ -65,12 +68,24 @@ module.exports = React.createClass({
mailboxDispatch.off('reload', this.handleReload)
mailboxDispatch.off('openMessage', this.handleOpenMessage)
mailboxDispatch.unrespond('fetch-process-memory-info', this.handleFetchProcessMemoryInfo)
mailboxDispatch.unrespond('get-gmail-unread-count:' + this.props.mailboxId, this.handleGetGmailUnreadCount)
ipcRenderer.removeListener('mailbox-window-find-start', this.handleIPCSearchStart)
ipcRenderer.removeListener('mailbox-window-find-next', this.handleIPCSearchNext)
ipcRenderer.removeListener('mailbox-window-navigate-back', this.handleIPCNavigateBack)
ipcRenderer.removeListener('mailbox-window-navigate-forward', this.handleIPCNavigateForward)
},

componentWillReceiveProps (nextProps) {
if (this.props.mailboxId !== nextProps.mailboxId) {
mailboxDispatch.unrespond('get-gmail-unread-count:' + this.props.mailboxId, this.handleGetGmailUnreadCount)
mailboxDispatch.respond('get-gmail-unread-count:' + nextProps.mailboxId, this.handleGetGmailUnreadCount)
ipcRenderer.send('prepare-webview-session', {
partition: 'persist:' + nextProps.mailboxId
})
this.setState(this.getInitialState(nextProps))
}
},

/* **************************************************************************/
// Data lifecycle
/* **************************************************************************/
Expand All @@ -90,15 +105,6 @@ module.exports = React.createClass({
}
},

componentWillReceiveProps (nextProps) {
if (this.props.mailboxId !== nextProps.mailboxId) {
ipcRenderer.send('prepare-webview-session', {
partition: 'persist:' + nextProps.mailboxId
})
this.setState(this.getInitialState(nextProps))
}
},

mailboxesChanged (store) {
const mailbox = store.getMailbox(this.props.mailboxId)
if (mailbox) {
Expand Down Expand Up @@ -212,6 +218,16 @@ module.exports = React.createClass({
})
},

/**
* Fetches the gmail unread count
* @return promise
*/
handleGetGmailUnreadCount () {
return this.refs.browser.sendWithResponse('get-gmail-unread-count', {}, 1000).then((res) => {
return Promise.resolve({ count: res.count })
})
},

/* **************************************************************************/
// Browser Events : Dispatcher
/* **************************************************************************/
Expand All @@ -225,7 +241,7 @@ module.exports = React.createClass({
case 'page-click': this.handleBrowserPageClick(evt); break
case 'open-settings': navigationDispatch.openSettings(); break
case 'js-new-window': this.handleBrowserJSNewWindow(evt); break
default:
default: break
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = React.createClass({

const sizeToMb = (size) => { return Math.round(size / 1024) }

mailboxDispatch.request('fetch-process-memory-info').then((mailboxesProc) => {
mailboxDispatch.fetchProcessMemoryInfo().then((mailboxesProc) => {
const mailboxProcIndex = mailboxesProc.reduce((acc, info) => {
acc[info.mailboxId] = info.memoryInfo
return acc
Expand Down
3 changes: 1 addition & 2 deletions src/scenes/platform/src/webviewInjection/Browser/Browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ class Browser {

ipcRenderer.on('get-process-memory-info', (evt, data) => {
ipcRenderer.sendToHost({
id: data.id,
data: process.getProcessMemoryInfo(),
type: 'respond-process-memory-info'
type: data.__respond__
})
})
}
Expand Down
15 changes: 15 additions & 0 deletions src/scenes/platform/src/webviewInjection/Google/Google.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Google {
// Bind our listeners
ipcRenderer.on('window-icons-in-screen', this.handleWindowIconsInScreenChange.bind(this))
ipcRenderer.on('open-message', this.handleOpenMesage.bind(this))
ipcRenderer.on('get-gmail-unread-count', this.handleFetchUnreadCount.bind(this))

if (this.isGmail) {
this.loadGmailAPI()
Expand Down Expand Up @@ -106,6 +107,20 @@ class Google {
window.location.hash = 'inbox/' + data.messageId
}
}

/**
* Handles fetching the unread count out the dom
* @param evt: the event that fired
* @param data: the data that was sent with the event
*/
handleFetchUnreadCount (evt, data) {
ipcRenderer.sendToHost({
type: data.__respond__,
data: {
count: !this.gmailApi ? undefined : this.gmailApi.get.unread_inbox_emails()
}
})
}
}

module.exports = Google

0 comments on commit 3c4903f

Please sign in to comment.