Skip to content

Commit

Permalink
latest
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe Edelman committed Apr 5, 2016
1 parent 4c09ad0 commit 20bbf87
Show file tree
Hide file tree
Showing 40 changed files with 125 additions and 1,701 deletions.
10 changes: 0 additions & 10 deletions .gitignore
@@ -1,15 +1,5 @@
_old

site/compiled.js
api/node_modules
site/compiled.map
vendor.js
compiled.js
compiled.map
all.css
node_modules
_build
katon.log
_untracked
.DS_Store
background.js
Expand Down
109 changes: 28 additions & 81 deletions TODO.md
@@ -1,90 +1,37 @@
## hindsight / reasons classes
## TODO

m1 - card is no longer bullshit / contains actual usage numbers
m2 - card submits to database
m3 - eyeball updates
---
m4 - reasons browser has new types, & can add reasons
m5 - card demands reasons
---
m6 - multiple correct cards appear
m7 - reasons browser can add synonyms etc
m8 - card looks nice
- publish chrome-activities to npm
- remove reasons, chrome activities from npm links

VERIFY LOGIN
- update manifest oauth2 details
- package hindsight and send to chrome store
- install from store in other chrome

RELEASES
- link to hindsight from talk page
- push hindsight to chrome registry
- FIX: assessement "Not good for this"
https://www.firebase.com/docs/security/guide/user-security.html
- https://www.firebase.com/pricing.html

TODO:
* chromeActivities should be able to restart trails on extension reload


====

m1 **2h**
PRE-RELEASE???
- test in older chrome
- firebase data access rules
- implement Reasons.commonForActivity()
- reindexReasons() doesn't work with new compactReasons / terms database?
- don't repeatedly ask hindsight users to login
- google-group for chrome-activities and reasons

* hindsight shell
* minimal Composer
* minimal assessments/Card
* assessments/storage#saveAssessment()
* storage#createReason()

m2

* Composer **2h**
* assessments/Card **1h**
* assessments/ActivityExplanationView **15m**

m3

* Composer - posts to src/storage (2h)
* src/storage - **1h**

#suggestedReasons(url) => promise?
#create(type, text, cb(newId))
#find(id) => promise?
#completions(str)

* src/EntryField - pulls from src/storage (20m)
* src/SuggestionsList - also pulls from src/storage (30m)

m4

* src/assessments/storage -

browserHistory.js
timelines.js
index.js **2h**
#isAssessed?(uid,url)
#unassessedActivities(uid, url) => activity[]
#recentAssessedActivities(uid, url) => activity[]
#saveAssessment(uid, activity, reasons, disposition)

m5

* assessments/Card - generated from assessments/storage




**7h**


src/assessments

PastAssessmentsList **30m**








## Data formats:

activity = {
url: "",
timeframe: [],
timeline: {},
headline: "",
details: "",
urls: []
}
POST-RELEASE
- fix up eyeball images
- reasons browser can add synonyms etc
- gather betterOptions and fulfillments
- document models for activities/dispositions/assessments/reasons
- document models for usage/trails
- compact representations for reasons and terms
158 changes: 89 additions & 69 deletions background.jsx
@@ -1,95 +1,115 @@
let ReactDOM = require('react-dom'),
React = require('react'),
Component = React.Component
import React from 'react'
import ReactDOM from 'react-dom'
import { Button } from 'react-ratchet'

import Activities from 'chrome-activities'

let { NavBar, NavButton, Title } = require('react-ratchet')

import ReasonBrowser from 'reasons/browser.jsx'
import AssessmentCard from 'reasons/activities/card.jsx'


Activities.monitorActivities(a => {

console.log('current activity', a)
// adjustEyeball
import Firebase from 'firebase'
let FIREBASE = new Firebase('https://lifestyles.firebaseio.com/')

// a.elapsed
import Activities from 'chrome-activities'
Activities.trackActivities()

import Reasons from 'reasons'
import ReviewPanel from 'reasons/activities/reviewPage.jsx'
import LocalReviews from 'reasons/activities/localReviews'


Activities.onActivityChanged(a => {
console.log("onActivityChanged", a)
let d = LocalReviews.forActivity(a)

var eyeImage
if (d){
if (d == 'skip') eyeImage = 'clear'
if (d == 'bad') eyeImage = 'red'
else eyeImage = 'green'
} else {
if (a.elapsed > 20*60*1000) eyeImage = 'redside'
else if (a.elapsed > 10*60*1000) eyeImage = 'side'
else eyeImage = 'clear'
}

// no review:
// clear => not time to review yet, and no review
// side eye => time to review!
// review:
// red => you don't like this site
// heart => you like this site
console.log('updating eyeball', a.elapsed, d, `images/eyes/${eyeImage}.png`)
chrome.browserAction.setIcon({path:`images/eyes/${eyeImage}.png`})
})


window.showPopup = el => {
withGooglePlusIdentity( p => {
Activities.withUnreviewed(all => {
ReactDOM.render(<Popup user={p} newActivities={all} />, el )
})
})
ReactDOM.render( <PopupContainer activitySource={Activities} />, el )
}

class Popup extends Component {
render(){
if (this.state && this.state.show == 'reasons'){
return <ReasonBrowser onClose={()=>this.setState({show:false})}/>
} else {
return <ReviewPanel {...this.props} compose={()=>this.setState({show:'reasons'})} />
}
}
function signIn(){
if (FIREBASE.getAuth()) return
chrome.identity.getAuthToken({interactive: true}, tok => {
FIREBASE.authWithOAuthToken('google', tok, err => {
if (err) console.log(err)

// registerUser
fetch('https://www.googleapis.com/plus/v1/people/me', {
headers: { 'Authorization': 'Bearer ' + tok },
}).then(r => r.json()).then(response => {
if (!response || !response.id) return;
Reasons.registerUser({
plusID: response.id,
gender: response.gender,
name: response.displayName,
location: response.currentLocation,
image: response.image && response.image.url,
language: response.language,
email: response.emails && response.emails[0] && response.emails[0].value
})
}).catch(ex => console.error(ex))
})
})
}

const ReviewPanel = (props) => (
<div>
<NavBar>
<NavButton right icon="compose" onClick={props.compose} />
<Title>Assess!</Title>
</NavBar>
<div className="content">{
props.newActivities.map(a => (
<AssessmentCard user={props.user} activity={a}/>
))
}</div>
const PleaseSignIn = () => (
<div className="content content-padded">
<h3>Welcome to Hindsight!</h3>
<p>
As you browse, you'll see an eyeball icon on chrome. When Hindsight thinks you might want to review whatever you're doing to see if it's really helpful for yourself and for others, the eyeball will turn to look at the URL bar to the left of it. If Hindsight thinks you should probably take a break the eyeball will turn red and bloodshot. If Hindsight understands how you're using the web enough to know you're on track, the iris of the eyeball turns green!
</p>
<p>In order to send your reviews in to be counter, we'll need you to sign in. We only collect your email address, and we won't connected it with data from your web use.</p>
<Button onClick={signIn}>
Sign in
</Button>
</div>
)

class PopupContainer extends React.Component {
constructor(props){
super(props)
this.state = {auth: FIREBASE.getAuth()}
}

updateAuth(data){
this.setState({auth: data})
}

componentWillMount(){
FIREBASE.onAuth(this.updateAuth, this)
}

function withGooglePlusIdentity(cb){
if (localStorage.plusID) return cb(JSON.parse(localStorage.plusID))
chrome.identity.getAuthToken({interactive: true}, (authToken) => {
fetch('https://www.googleapis.com/plus/v1/people/me', {
headers: { 'Authorization': 'Bearer ' + authToken },
}).then(r => r.json()).then(response => {
if (!response || !response.id) return;
var identity = {
id: "plus:" + response.id,
plusid: response.id,
gender: response.gender,
name: response.displayName,
location: response.currentLocation,
image: response.image && response.image.url,
language: response.language,
email: response.emails && response.emails[0] && response.emails[0].value
}
localStorage.plusID = JSON.stringify(identity)
cb(identity)
}).catch(ex => console.error(ex))
})
}

componentWillUnmount(){
FIREBASE.offAuth(this.updateAuth, this)
}

render(){
let { auth } = this.state
if (!auth) return <PleaseSignIn/>
else return <ReviewPanel
wasReviewed={a => Activities.wasReviewed(a)}
activitySource={() => Activities.forReview()}
/>
}
}





// function withGooglePlusIdentity(cb){
// if (localStorage.plusID) return cb(JSON.parse(localStorage.plusID))
// }

//
// chrome.tabs.query({active:true, currentWindow:true}, tabs => {
Expand Down
Binary file added images/eye-small.pxm
Binary file not shown.
Binary file added images/eye.pxm
Binary file not shown.
Binary file added images/eyes/clear.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/eyes/eye-bloodshot-big.png
Binary file not shown.
Binary file removed images/eyes/eye-bloodshot.png
Binary file not shown.
Binary file added images/eyes/green.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added images/eyes/red.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/eyes/redside.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/eyes/side.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions manifest.json
Expand Up @@ -21,12 +21,12 @@
"version": "0.3.0",
"author": "Joe Edelman",
"icons": {
"128": "images/eyes/eye-bloodshot.png",
"48": "images/eyes/eye-bloodshot.png"
"128": "images/eyes/clear.png",
"48": "images/eyes/clear.png"
},

"browser_action": {
"default_icon": "images/eyes/eye-bloodshot.png",
"default_icon": "images/eyes/clear.png",
"default_name": "Hindsight",
"default_title": "Hindsight",
"default_popup": "popup.html"
Expand Down

0 comments on commit 20bbf87

Please sign in to comment.