1
0
mirror of https://github.com/beestat/app.git synced 2025-05-24 02:14:03 -04:00

Fixed #208 - Can't link Patreon account if you've closed the banner.

For good this time.
This commit is contained in:
Jon Ziebell 2020-01-21 21:48:32 -05:00
parent 5e1ee836b7
commit 05b24f858e
16 changed files with 273 additions and 123 deletions

View File

@ -43,6 +43,10 @@ class patreon extends external_api {
echo '<html><head><title></title></head><body><script type="text/javascript">window.close();</script></body></html><!--';
$this->cora->set_headers([
'Content-Type' => 'text/html'
], true);
// Need to commit the transaction so the stuff gets saved.
$this->database->commit_transaction();
}

View File

@ -164,21 +164,6 @@ window.addEventListener('resize', rocket.throttle(100, function() {
});
}));
/**
* Whether or not the current user gets access to early release features.
*
* @return {boolean} Early access or not.
*/
beestat.has_early_access = function() {
var user = beestat.get_user();
return user.user_id === 1 ||
(
user.patreon_status !== null &&
user.patreon_status.patron_status === 'active_patron' &&
user.patreon_status.currently_entitled_amount_cents >= 500
);
};
// First run
var $ = rocket.extend(rocket.$, rocket);
$.ready(function() {

View File

@ -34,7 +34,6 @@ beestat.disable_poll = function() {
* Poll the database for changes and update the cache.
*/
beestat.poll = function() {
var api = new beestat.api();
api.add_call(
@ -101,5 +100,6 @@ beestat.poll = function() {
api.send();
};
beestat.default_poll_interval = 300000; // 5 minutes
// Five minutes
beestat.default_poll_interval = 300000;
beestat.poll_intervals = [beestat.default_poll_interval];

View File

@ -9,7 +9,7 @@
* otherwise.
*/
beestat.setting = function(key, opt_value, opt_callback) {
var user = beestat.get_user();
var user = beestat.user.get();
var defaults = {
'runtime_thermostat_detail_smoothing': true,

48
js/beestat/user.js Normal file
View File

@ -0,0 +1,48 @@
beestat.user = {};
/**
* Determine whether or not the current user is an active Patron.
*
* @return {boolean} true if yes, false if no.
*/
beestat.user.patreon_is_active = function() {
var user = beestat.user.get();
return (
user.patreon_status !== null &&
user.patreon_status.patron_status === 'active_patron'
);
};
/**
* Is the user connected to Patreon.
*
* @return {boolean} true if yes, false if no.
*/
beestat.user.patreon_is_connected = function() {
return beestat.user.get().patreon_status !== null;
};
/**
* Whether or not the current user gets access to early release features.
*
* @return {boolean} Early access or not.
*/
beestat.user.has_early_access = function() {
var user = beestat.user.get();
return user.user_id === 1 ||
(
user.patreon_status !== null &&
user.patreon_status.patron_status === 'active_patron' &&
user.patreon_status.currently_entitled_amount_cents >= 500
);
};
/**
* Get the current user.
*
* @return {object} The current user.
*/
beestat.user.get = function() {
var user_id = Object.keys(beestat.cache.user)[0];
return beestat.cache.user[user_id];
};

View File

@ -85,6 +85,7 @@ beestat.component.prototype.dispose = function() {
var child = this.component_container_.parentNode();
var parent = child.parentNode();
parent.removeChild(child);
this.rendered_ = false;
};
beestat.component.prototype.decorate_ = function() {

View File

@ -2,11 +2,27 @@
* Green Patreon banner asking people for money. $_$
*/
beestat.component.card.patreon = function() {
var self = this;
beestat.dispatcher.addEventListener('cache.user', function() {
self.rerender();
});
beestat.component.card.apply(this, arguments);
};
beestat.extend(beestat.component.card.patreon, beestat.component.card);
beestat.component.card.patreon.prototype.decorate_contents_ = function(parent) {
var self = this;
// Don't render anything if the user is an active Patron.
if (beestat.component.card.patreon.should_show() === false) {
setTimeout(function() {
self.dispose();
}, 0);
return;
}
parent.style('background', beestat.style.color.green.base);
new beestat.component.button()
@ -45,3 +61,23 @@ beestat.component.card.patreon.prototype.decorate_top_right_ = function(parent)
})
.render(parent);
};
/**
* Determine whether or not this card should be shown.
*
* @return {boolean} Whether or not to show the card.
*/
beestat.component.card.patreon.should_show = function() {
if (
beestat.user.patreon_is_active() === true ||
window.is_demo === true ||
(
beestat.setting('patreon_hide_until') !== undefined &&
moment.utc(beestat.setting('patreon_hide_until')).isAfter(moment.utc())
)
) {
return false;
}
return true;
};

View File

@ -8,7 +8,10 @@ beestat.component.header = function(active_layer) {
this.active_layer_ = active_layer;
beestat.dispatcher.addEventListener('view_announcements', function() {
beestat.dispatcher.addEventListener([
'view_announcements',
'cache.user'
], function() {
self.rerender();
});
@ -23,7 +26,7 @@ beestat.component.header.prototype.decorate_ = function(parent) {
var pages;
if (beestat.has_early_access() === true) {
if (beestat.user.has_early_access() === true) {
pages = [
{
'layer': 'dashboard',
@ -174,12 +177,22 @@ beestat.component.header.prototype.decorate_ = function(parent) {
(new beestat.component.modal.download_data()).render();
}));
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Link Patreon')
.set_icon('patreon')
.set_callback(function() {
(new beestat.component.modal.enjoy_beestat()).render();
}));
if (beestat.user.patreon_is_connected() === false) {
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Link Patreon')
.set_icon('patreon')
.set_callback(function() {
(new beestat.component.modal.patreon_status()).render();
window.open('../api/?resource=patreon&method=authorize&arguments={}&api_key=ER9Dz8t05qUdui0cvfWi5GiVVyHP6OB8KPuSisP2');
}));
} else {
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Patreon Status')
.set_icon('patreon')
.set_callback(function() {
(new beestat.component.modal.patreon_status()).render();
}));
}
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Log Out')

View File

@ -30,9 +30,6 @@ beestat.component.layout.prototype.decorate_ = function(parent) {
row_element.appendChild(column_element);
column.card.render(column_element);
if (column.global !== undefined) {
beestat.cards[column.global] = column.card;
}
});
});
};

View File

@ -160,6 +160,8 @@ beestat.component.modal.prototype.dispose = function() {
$(window).removeEventListener('keydown.modal');
$(window).removeEventListener('click.modal');
this.rendered_ = false;
};
/**
@ -168,10 +170,12 @@ beestat.component.modal.prototype.dispose = function() {
* all the fancy animation and that is not desirable when rerendering.
*/
beestat.component.modal.prototype.rerender = function() {
this.modal_content_.innerHTML('');
this.decorate_header_(this.modal_content_);
this.decorate_contents_(this.modal_content_);
this.decorate_buttons_(this.modal_content_);
if (this.rendered_ === true) {
this.modal_content_.innerHTML('');
this.decorate_header_(this.modal_content_);
this.decorate_contents_(this.modal_content_);
this.decorate_buttons_(this.modal_content_);
}
};
/**

View File

@ -6,22 +6,20 @@ beestat.component.modal.enjoy_beestat = function() {
};
beestat.extend(beestat.component.modal.enjoy_beestat, beestat.component.modal);
beestat.component.modal.enjoy_beestat.poll_interval_ = 5000;
/**
* Decorate
*
* @param {rocket.Elements} parent
*/
beestat.component.modal.enjoy_beestat.prototype.decorate_contents_ = function(parent) {
switch (this.is_active_patron_()) {
case false:
if (
beestat.user.patreon_is_connected() === true &&
beestat.user.patreon_is_active() === false
) {
parent.appendChild($.createElement('p').innerText('Your Patreon account is connected but you\'re not currently a supporter. If you recently became a supporter it could take up to 24 hours to update.'));
break;
case null:
parent.appendChild($.createElement('p').innerHTML('If you didn\'t notice, beestat doesn\'t run ads, charge money, or sell your data. If you find beestat useful, <strong>please consider supporting the project on <a href="https://patreon.com/beestat" target="_blank" class="inverted">Patreon</a>.</strong> Your contribution helps pay for servers, storage, and other cool things. Thanks!'));
parent.appendChild($.createElement('p').innerHTML('Not into Patreon? <a href="https://www.notion.so/beestat/Support-Beestat-bf7f099eb8de486bad51aa6245c00891" target="_blank" class="inverted">Here are some other ways to help</a>.'));
break;
} else {
parent.appendChild($.createElement('p').innerHTML('Beestat is completely free to use and does not run ads or sell your data. If you want to help, <strong>consider supporting the project on <a href="https://patreon.com/beestat" target="_blank" class="inverted">Patreon</a></strong>. Among other benefits, it will hide this banner permanently.'));
parent.appendChild($.createElement('p').innerHTML('Not into Patreon or can\'t afford to give? <a href="https://www.notion.so/beestat/Support-Beestat-bf7f099eb8de486bad51aa6245c00891" target="_blank" class="inverted">Here are some other ways to help</a>.'));
}
};
@ -34,19 +32,6 @@ beestat.component.modal.enjoy_beestat.prototype.get_title_ = function() {
return 'Enjoy beestat?';
};
/**
* Close the modal but run some special code first to make sure any running
* interval gets stopped.
*/
beestat.component.modal.enjoy_beestat.prototype.dispose = function() {
if (this.is_polling_ === true) {
beestat.remove_poll_interval(beestat.component.modal.enjoy_beestat.poll_interval_);
beestat.dispatcher.removeEventListener('poll.enjoy_beestat');
}
beestat.component.modal.prototype.dispose.apply(this, arguments);
};
/**
* Hide the Patreon card for some amount of time.
*
@ -63,19 +48,6 @@ beestat.component.modal.enjoy_beestat.prototype.hide_patreon_card_for_ = functio
beestat.cards.patreon.dispose();
};
/**
* Determine whether or not the current user is an active Patron.
*
* @return {boolean} true if yes, false if no, null if not connected.
*/
beestat.component.modal.enjoy_beestat.prototype.is_active_patron_ = function() {
var user = beestat.get_user();
if (user.patreon_status !== null) {
return (user.patreon_status.patron_status === 'active_patron');
}
return null;
};
/**
* Get the buttons on the modal.
*
@ -94,37 +66,15 @@ beestat.component.modal.enjoy_beestat.prototype.get_buttons_ = function() {
self.dispose();
});
if (self.is_active_patron_() === null) {
if (beestat.user.patreon_is_connected() === false) {
var link = new beestat.component.button()
.set_text('Link Patreon')
.set_background_color(beestat.style.color.green.base)
.set_background_hover_color(beestat.style.color.green.light)
.set_text_color('#fff')
.addEventListener('click', function() {
this
.set_background_color(beestat.style.color.gray.base)
.set_background_hover_color()
.set_text('Waiting for Patreon...')
.removeEventListener('click');
beestat.add_poll_interval(beestat.component.modal.enjoy_beestat.poll_interval_);
self.is_polling_ = true;
beestat.dispatcher.addEventListener('poll.enjoy_beestat', function() {
switch (self.is_active_patron_()) {
case true:
// Connected and is Patron
beestat.cards.patreon.dispose();
self.dispose();
break;
case false:
// Connected but isn't Patron
self.hide_patreon_card_for_(3, 'day');
self.dispose();
break;
}
});
self.dispose();
(new beestat.component.modal.patreon_status()).render();
window.open('../api/?resource=patreon&method=authorize&arguments={}&api_key=ER9Dz8t05qUdui0cvfWi5GiVVyHP6OB8KPuSisP2');
});

View File

@ -0,0 +1,136 @@
/**
* Patreon Status.
*/
beestat.component.modal.patreon_status = function() {
beestat.component.modal.apply(this, arguments);
};
beestat.extend(beestat.component.modal.patreon_status, beestat.component.modal);
beestat.component.modal.patreon_status.prototype.decorate_contents_ = function(parent) {
var user = beestat.user.get();
if (user.patreon_status === null) {
this.decorate_wait_(parent);
} else {
this.decorate_status_(parent);
}
};
/**
* Do some wait logic and get an updated user every 5 seconds.
*
* @param {rocket.Elements} parent
*/
beestat.component.modal.patreon_status.prototype.decorate_wait_ = function(parent) {
var self = this;
parent.appendChild(
$.createElement('div')
.style({
'margin-top': beestat.style.size.gutter
})
.innerText('Waiting for Patreon to connect...')
);
var api = new beestat.api();
api.add_call('user', 'read_id');
api.set_callback(function(response) {
beestat.cache.set('user', response);
self.rerender();
});
setTimeout(function() {
api.send();
}, 5000);
};
/**
* Decorate the patreon details if they exist.
*
* @param {rocket.Elements} parent
*/
beestat.component.modal.patreon_status.prototype.decorate_status_ = function(parent) {
var user = beestat.user.get();
// Create our number formatter.
var formatter = new Intl.NumberFormat(
'en-US',
{
'style': 'currency',
'currency': 'USD'
}
);
var container = $.createElement('div')
.style({
'display': 'grid',
'grid-template-columns': 'repeat(auto-fill, minmax(150px, 1fr))',
'margin': '0 0 16px -16px'
});
parent.appendChild(container);
var status;
switch (user.patreon_status.patron_status) {
case 'active_patron':
status = 'Active Patron';
break;
case 'declined_patron':
status = 'Declined Patron';
break;
case 'former_patron':
status = 'Former Patron';
break;
default:
status = 'Unknown';
break;
}
var last_charged;
if (user.patreon_status.last_charge_date === null) {
last_charged = 'Never';
} else {
last_charged = moment.utc(user.patreon_status.last_charge_date).local()
.format('MMM Do, YYYY');
}
var fields = [
{
'name': 'Status',
'value': status
},
{
'name': 'Last Charged',
'value': last_charged
},
{
'name': 'Current Pledge',
'value': formatter.format(user.patreon_status.will_pay_amount_cents / 100)
},
{
'name': 'Lifetime Support',
'value': formatter.format(user.patreon_status.lifetime_support_cents / 100)
}
];
fields.forEach(function(field) {
var div = $.createElement('div')
.style({
'padding': '16px 0 0 16px'
});
container.appendChild(div);
div.appendChild($.createElement('div')
.style({
'font-weight': beestat.style.font_weight.bold,
'margin-bottom': (beestat.style.size.gutter / 4)
})
.innerHTML(field.name));
div.appendChild($.createElement('div').innerHTML(field.value));
});
};
beestat.component.modal.patreon_status.prototype.get_title_ = function() {
return 'Patreon Status';
};

View File

@ -34,10 +34,6 @@ beestat.component.modal.thermostat_info.prototype.decorate_contents_ = function(
'name': 'Firmware Revision',
'value': ecobee_thermostat.version.thermostatFirmwareVersion
},
{
'name': 'Weather Station',
'value': ecobee_thermostat.weather.weatherStation
},
{
'name': 'First Connected',
'value': moment.utc(ecobee_thermostat.runtime.firstConnected).local()

View File

@ -30,6 +30,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
echo '<script src="/js/beestat/home_comparisons.js"></script>' . PHP_EOL;
echo '<script src="/js/beestat/highcharts.js"></script>' . PHP_EOL;
echo '<script src="/js/beestat/get_sync_progress.js"></script>' . PHP_EOL;
echo '<script src="/js/beestat/user.js"></script>' . PHP_EOL;
// Layer
echo '<script src="/js/layer.js"></script>' . PHP_EOL;
@ -84,6 +85,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
echo '<script src="/js/component/modal/runtime_sensor_detail_custom.js"></script>' . PHP_EOL;
echo '<script src="/js/component/modal/thermostat_info.js"></script>' . PHP_EOL;
echo '<script src="/js/component/modal/weather.js"></script>' . PHP_EOL;
echo '<script src="/js/component/modal/patreon_status.js"></script>' . PHP_EOL;
echo '<script src="/js/component/input.js"></script>' . PHP_EOL;
echo '<script src="/js/component/input/text.js"></script>' . PHP_EOL;
echo '<script src="/js/component/button.js"></script>' . PHP_EOL;

View File

@ -46,33 +46,11 @@ beestat.layer.dashboard.prototype.decorate_ = function(parent) {
}
]);
// Show the Patreon card by default; look for reasons to hide it.
var show_patreon_card = true;
var user = beestat.get_user();
if (
user.patreon_status !== null &&
user.patreon_status.patron_status === 'active_patron'
) {
show_patreon_card = false;
}
if (
(
beestat.setting('patreon_hide_until') !== undefined &&
moment.utc(beestat.setting('patreon_hide_until')).isAfter(moment.utc())
) ||
window.is_demo === true
) {
show_patreon_card = false;
}
if (show_patreon_card === true) {
if (beestat.component.card.patreon.should_show() === true) {
cards.push([
{
'card': new beestat.component.card.patreon(),
'size': 12,
'global': 'patreon' // TODO REMOVE THIS
'size': 12
}
]);
}

View File

@ -136,10 +136,10 @@ beestat.layer.load.prototype.decorate_ = function(parent) {
Rollbar.configure({
'payload': {
'person': {
'id': beestat.get_user().user_id
'id': beestat.user.get().user_id
},
'beestat': {
'user_id': beestat.get_user().user_id
'user_id': beestat.user.get().user_id
}
}
});