mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-08-05 12:02:13 +00:00
commit
114cbe2760
13 changed files with 184 additions and 43 deletions
2
.buildpacks
Normal file
2
.buildpacks
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
https://github.com/heroku/heroku-buildpack-nodejs.git
|
||||
https://github.com/stomita/heroku-buildpack-phantomjs.git
|
||||
|
|
@ -25,5 +25,11 @@
|
|||
"PAYPAL_SIGNATURE": "PAYPAL_SIGNATURE",
|
||||
"EMAIL_SERVER_URL": "http://example.com",
|
||||
"EMAIL_SERVER_AUTH_USER": "user",
|
||||
"EMAIL_SERVER_AUTH_PASSWORD": "password"
|
||||
"EMAIL_SERVER_AUTH_PASSWORD": "password",
|
||||
"S3":{
|
||||
"bucket":"bucket",
|
||||
"accessKeyId":"accessKeyId",
|
||||
"secretAccessKey":"secretAccessKey"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"main": "./src/server.js",
|
||||
"dependencies": {
|
||||
"async": "~0.9.0",
|
||||
"aws-sdk": "^2.0.25",
|
||||
"bower": "~1.3.12",
|
||||
"coffee-script": "1.6.x",
|
||||
"connect-ratelimit": "0.0.7",
|
||||
|
|
@ -25,17 +26,18 @@
|
|||
"grunt-nodemon": "~0.3.0",
|
||||
"habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared#develop",
|
||||
"icalendar": "git://github.com/lefnire/node-icalendar#master",
|
||||
"jade": "~1.7.0",
|
||||
"js2xmlparser": "~0.1.2",
|
||||
"lodash": "~2.4.1",
|
||||
"jade": "~1.7.0",
|
||||
"method-override": "~2.2.0",
|
||||
"mongoose": "~3.8.17",
|
||||
"moment": "~2.8.3",
|
||||
"mongoose": "~3.8.17",
|
||||
"mongoose-id-autoinc": "~2013.7.14-4",
|
||||
"nconf": "~0.6.9",
|
||||
"newrelic": "~1.11.2",
|
||||
"nib": "~1.0.1",
|
||||
"nodemailer": "~0.5.2",
|
||||
"pageres": "^1.0.1",
|
||||
"passport": "~0.2.1",
|
||||
"passport-facebook": "Fonger/passport-facebook#a8f98adcddad99caa9a918bc7b76462c92c5c9fd",
|
||||
"paypal-express-checkout": "git://github.com/HabitRPG/node-paypal-express-checkout#habitrpg",
|
||||
|
|
@ -43,6 +45,7 @@
|
|||
"paypal-recurring": "git://github.com/jaybryant/paypal-recurring#656b496f43440893c984700191666a5c5c535dca",
|
||||
"pretty-data": "git://github.com/vkiryukhin/pretty-data#master",
|
||||
"request": "~2.44.0",
|
||||
"s3-upload-stream": "^1.0.6",
|
||||
"stripe": "*",
|
||||
"swagger-node-express": "git://github.com/lefnire/swagger-node-express#habitrpg",
|
||||
"universal-analytics": "~0.3.2",
|
||||
|
|
|
|||
|
|
@ -73,7 +73,17 @@ future re: pets and whatnot, this is just temporary.
|
|||
&.isUser
|
||||
background: $color-herobox // Set a different background color for the current user
|
||||
&:hover, &:focus
|
||||
background: lighten($color-herobox, 16.18%)
|
||||
background: lighten($color-herobox, 16.18%)
|
||||
|
||||
.addthis_pill_style
|
||||
width: 50px !important
|
||||
.addthis_native_toolbox
|
||||
position: absolute
|
||||
top:2px
|
||||
right:2px
|
||||
opacity:0
|
||||
&:hover .addthis_native_toolbox
|
||||
opacity:1
|
||||
|
||||
//Need to find a way to indicate who is leader without using background-color as it won't work when a background image is applied
|
||||
//.herobox.isLeader.noBackgroundImage
|
||||
|
|
|
|||
|
|
@ -39,7 +39,17 @@
|
|||
// Scripts only for desktop
|
||||
if (!window.env.IS_MOBILE) {
|
||||
// Add This
|
||||
$.getScript("//s7.addthis.com/js/250/addthis_widget.js#pubid=lefnire");
|
||||
//$.getScript("//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5016f6cc44ad68a4"); //FIXME why isn't this working when here? instead it's now in <head>
|
||||
var addthisServices = 'facebook,twitter,googleplus,tumblr,'+window.env.BASE_URL.replace('https://','').replace('http://','');
|
||||
window.addthis_config = {
|
||||
services_custom:{
|
||||
name: "Download",
|
||||
url: window.env.BASE_URL+"/export/avatar-"+User.user._id+".png",
|
||||
icon: window.env.BASE_URL+"/favicon.ico"
|
||||
},
|
||||
services_expanded:addthisServices,
|
||||
services_compact:addthisServices
|
||||
};
|
||||
|
||||
// Google Charts
|
||||
$.getScript("//www.google.com/jsapi", function() {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,21 @@ window.habitrpgStatic = angular.module('habitrpgStatic', ['notificationServices'
|
|||
.constant("STORAGE_SETTINGS_ID", 'habit-mobile-settings')
|
||||
.constant("MOBILE_APP", false)
|
||||
|
||||
.controller("RootCtrl", ['$scope', '$location', '$modal', '$http', function($scope, $location, $modal, $http){
|
||||
// must be #?memberId=xx, see https://github.com/angular/angular.js/issues/7239
|
||||
var memberId = $location.search()['memberId'];
|
||||
if (memberId) {
|
||||
$http.get('/api/v2/members/'+memberId).success(function(data, status, headers, config){
|
||||
$scope.profile = data;
|
||||
$scope.Content = window.habitrpgShared.content;
|
||||
$modal.open({
|
||||
templateUrl: 'modals/member.html',
|
||||
scope: $scope
|
||||
});
|
||||
})
|
||||
}
|
||||
}])
|
||||
|
||||
.controller("PlansCtrl", ['$rootScope',
|
||||
function($rootScope) {
|
||||
$rootScope.clickContact = function(){
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@
|
|||
"bower_components/bootstrap/dist/css/bootstrap.css",
|
||||
"bower_components/css-social-buttons/css/zocial.css",
|
||||
"bower_components/jquery-colorbox/example1/colorbox.css",
|
||||
"app.css",
|
||||
"bower_components/habitrpg-shared/dist/habitrpg-shared.css",
|
||||
"static.css"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,13 @@ var js2xmlparser = require("js2xmlparser");
|
|||
var pd = require('pretty-data').pd;
|
||||
var User = require('../models/user').model;
|
||||
|
||||
// Avatar screenshot/static-page includes
|
||||
var Pageres = require('pageres'); //https://github.com/sindresorhus/pageres
|
||||
var AWS = require('aws-sdk');
|
||||
AWS.config.update({accessKeyId: nconf.get("S3:accessKeyId"), secretAccessKey: nconf.get("S3:secretAccessKey")});
|
||||
var s3Stream = require('s3-upload-stream')(new AWS.S3()); //https://github.com/nathanpeck/s3-upload-stream
|
||||
var bucket = nconf.get("S3:bucket");
|
||||
var request = require('request');
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------
|
||||
|
|
@ -83,3 +90,49 @@ expressres.jsonstring = function(obj, headers, status) {
|
|||
body = pd.json(JSON.stringify(obj));
|
||||
return this.send(body, headers, status);
|
||||
};
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------
|
||||
Static page and image screenshot of avatar
|
||||
------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
dataexport.avatarPage = function(req, res) {
|
||||
User.findById(req.params.uuid).select('stats profile items achievements preferences backer contributor').exec(function(err, user){
|
||||
res.render('avatar-static', {
|
||||
title: user.profile.name,
|
||||
env: _.defaults({user:user},res.locals.habitrpg)
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
dataexport.avatarImage = function(req, res, next) {
|
||||
var filename = 'avatar-'+req.params.uuid+'.png';
|
||||
request.head('https://'+bucket+'.s3.amazonaws.com/'+filename, function(err,response,body) {
|
||||
// cache images for 10 minutes on aws, else upload a new one
|
||||
if (response.statusCode==200 && moment().diff(response.headers['last-modified'], 'minutes') < 10)
|
||||
return res.redirect(301, 'https://' + bucket + '.s3.amazonaws.com/' + filename);
|
||||
new Pageres()//{delay:1}
|
||||
.src(nconf.get('BASE_URL') + '/export/avatar-' + req.params.uuid + '.html', ['140x147'], {crop: true, filename: filename.replace('.png', '')})
|
||||
.run(function (err, file) {
|
||||
if (err) return next(err);
|
||||
// see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createMultipartUpload-property
|
||||
var upload = s3Stream.upload({
|
||||
Bucket: bucket,
|
||||
Key: filename,
|
||||
ACL: "public-read",
|
||||
StorageClass: "REDUCED_REDUNDANCY",
|
||||
ContentType: "image/png",
|
||||
Expires: +moment().add({minutes: 3})
|
||||
});
|
||||
upload.on('error', function (err) {
|
||||
next(err);
|
||||
});
|
||||
upload.on('uploaded', function (details) {
|
||||
res.redirect(details.Location);
|
||||
});
|
||||
file[0].pipe(upload);
|
||||
});
|
||||
})
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@ var router = new express.Router();
|
|||
var dataexport = require('../controllers/dataexport');
|
||||
var auth = require('../controllers/auth');
|
||||
var nconf = require('nconf');
|
||||
var i18n = require('../i18n')
|
||||
var i18n = require('../i18n');
|
||||
var middleware = require('../middleware.js');
|
||||
|
||||
/* Data export */
|
||||
router.get('/history.csv',auth.authWithSession,i18n.getUserLanguage,dataexport.history); //[todo] encode data output options in the data controller and use these to build routes
|
||||
router.get('/userdata.xml',auth.authWithSession,i18n.getUserLanguage,dataexport.leanuser,dataexport.userdata.xml);
|
||||
router.get('/userdata.json',auth.authWithSession,i18n.getUserLanguage,dataexport.leanuser,dataexport.userdata.json);
|
||||
router.get('/avatar-:uuid.html', i18n.getUserLanguage, middleware.locals, dataexport.avatarPage);
|
||||
router.get('/avatar-:uuid.png', i18n.getUserLanguage, middleware.locals, dataexport.avatarImage);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
|||
28
views/avatar-static.jade
Normal file
28
views/avatar-static.jade
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
doctype html
|
||||
html(ng-app="habitrpg")
|
||||
head
|
||||
title=title
|
||||
link(rel='shortcut icon', href='#{env.getBuildUrl("favicon.ico")}?v=3')
|
||||
|
||||
meta(charset='utf-8')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1.0')
|
||||
meta(name='apple-mobile-web-app-capable', content='yes')
|
||||
|
||||
script(type='text/javascript').
|
||||
window.env = !{JSON.stringify(env)};
|
||||
|
||||
!= env.getManifestFiles("app")
|
||||
|
||||
script(type='text/javascript').
|
||||
window.habitrpg
|
||||
.controller('StaticAvatarCtrl', ['$scope', function($scope){
|
||||
$scope.profile = window.env.user;
|
||||
}])
|
||||
|
||||
//webfonts
|
||||
link(href='//fonts.googleapis.com/css?family=Lato:300,400,700,400italic,700italic', rel='stylesheet', type='text/css')
|
||||
|
||||
body(ng-cloak)
|
||||
include ./shared/header/avatar
|
||||
div(ng-controller='StaticAvatarCtrl')
|
||||
+herobox({main:true})
|
||||
|
|
@ -10,6 +10,9 @@ html(ng-app="habitrpg", ng-controller="RootCtrl", ng-class='{"applying-action":a
|
|||
meta(name='viewport', content='width=device-width, initial-scale=1.0')
|
||||
meta(name='apple-mobile-web-app-capable', content='yes')
|
||||
|
||||
//FIXME for some reason this won't load when in footerCtrl.js#deferredScripts()
|
||||
script(type="text/javascript", src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5016f6cc44ad68a4", async="async")
|
||||
|
||||
script(type='text/javascript').
|
||||
window.env = !{JSON.stringify(env)};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ mixin avatar(opts)
|
|||
|
||||
.character-sprites
|
||||
|
||||
.addthis_native_toolbox(ng-if='profile._id==user._id', data-url="#{env.BASE_URL}/static/front/#?memberId={{profile._id}}", data-title="Check out my HabitRPG progress!")
|
||||
|
||||
// Mount Body
|
||||
if !opts.minimal
|
||||
span(ng-if='profile.items.currentMount', class='Mount_Body_{{profile.items.currentMount}}')
|
||||
|
|
|
|||
|
|
@ -8,41 +8,45 @@ block title
|
|||
title=env.t('titleFront')
|
||||
|
||||
block content
|
||||
.marketing
|
||||
//we need to use something that's not jumbotron for this, but still keep it centered
|
||||
//could someone write something else to make it pretty?
|
||||
img(src='/bower_components/habitrpg-shared/img/logo/habitrpg_pixel.png', alt='HabitRPG logo')
|
||||
//this image needs to be replaced by something more enticing, that shows off the features of hRPG
|
||||
//while acting similarly to a logo
|
||||
h1#tagline=env.t('tagline')
|
||||
p.lead
|
||||
button.btn.btn-primary.btn-lg#frontpage-play-button(ng-click='playButtonClick()')=env.t('playButton')
|
||||
hr
|
||||
img(src='/marketing/devices.png')
|
||||
//we'd want the tagline centered, for sure, and a bit more pop, but without using jumbotron
|
||||
//it could also be part of the image, as long as the alt text included it
|
||||
//in fact, I think I really want it on the image, rather than as text, but language issues
|
||||
br
|
||||
p.lead=env.t('landingp1')
|
||||
h2=env.t('landingp2header')
|
||||
//images in these parts could be useful, too
|
||||
//if there's a language workaround, image headers? people like pictures!
|
||||
p.lead
|
||||
=env.t('landingp2')
|
||||
|
|
||||
h2=env.t('landingp3header')
|
||||
//I'm not sold on "Consquences as the title here. Anyone got a better idea?
|
||||
p.lead
|
||||
=env.t('landingp3')
|
||||
|
|
||||
h2=env.t('landingp4header')
|
||||
p.lead=env.t('landingp4')
|
||||
//- TODO
|
||||
h2=env.t('landingend')
|
||||
div(ng-controller='RootCtrl')
|
||||
include ../shared/header/avatar
|
||||
include ../shared/modals/members
|
||||
|
||||
.marketing
|
||||
//we need to use something that's not jumbotron for this, but still keep it centered
|
||||
//could someone write something else to make it pretty?
|
||||
img(src='/bower_components/habitrpg-shared/img/logo/habitrpg_pixel.png', alt='HabitRPG logo')
|
||||
//this image needs to be replaced by something more enticing, that shows off the features of hRPG
|
||||
//while acting similarly to a logo
|
||||
h1#tagline=env.t('tagline')
|
||||
p.lead
|
||||
=env.t('landingend2')
|
||||
a(href="FEATURESPAGEHERE")=env.t('landingfeatureslink')
|
||||
=env.t('landingend3')
|
||||
a(href="ENTERPRISEPAGEHERE")=env.t('landingadminlink')
|
||||
|
|
||||
=env.t('landingend4')
|
||||
button.btn.btn-primary.btn-lg#frontpage-play-button(ng-click='playButtonClick()')=env.t('playButton')
|
||||
hr
|
||||
img(src='/marketing/devices.png')
|
||||
//we'd want the tagline centered, for sure, and a bit more pop, but without using jumbotron
|
||||
//it could also be part of the image, as long as the alt text included it
|
||||
//in fact, I think I really want it on the image, rather than as text, but language issues
|
||||
br
|
||||
p.lead=env.t('landingp1')
|
||||
h2=env.t('landingp2header')
|
||||
//images in these parts could be useful, too
|
||||
//if there's a language workaround, image headers? people like pictures!
|
||||
p.lead
|
||||
=env.t('landingp2')
|
||||
|
|
||||
h2=env.t('landingp3header')
|
||||
//I'm not sold on "Consquences as the title here. Anyone got a better idea?
|
||||
p.lead
|
||||
=env.t('landingp3')
|
||||
|
|
||||
h2=env.t('landingp4header')
|
||||
p.lead=env.t('landingp4')
|
||||
//- TODO
|
||||
h2=env.t('landingend')
|
||||
p.lead
|
||||
=env.t('landingend2')
|
||||
a(href="FEATURESPAGEHERE")=env.t('landingfeatureslink')
|
||||
=env.t('landingend3')
|
||||
a(href="ENTERPRISEPAGEHERE")=env.t('landingadminlink')
|
||||
|
|
||||
=env.t('landingend4')
|
||||
|
|
|
|||
Loading…
Reference in a new issue