mirror of
https://github.com/beestat/app.git
synced 2025-05-23 18:04:14 -04:00
Fixed #266 - Migrate from MailChimp to MailGun
This commit is contained in:
parent
f909470b5d
commit
d0ce15606b
@ -111,19 +111,26 @@ final class setting {
|
||||
'beestat_root_uri' => '',
|
||||
|
||||
/**
|
||||
* Your Mailchimp API Key; provided to you when you create a Mailchimp
|
||||
* developer account.
|
||||
* Your Mailgun API Key.
|
||||
*
|
||||
* Example: hcU74TJgGS5k7vuw3NSzkRMSWNPkv8Af-us18
|
||||
* Example: 4b34e48e768fa45c4a6ac65dd4cf1da9-7e28d3c3-61713777
|
||||
*/
|
||||
'mailchimp_api_key' => '',
|
||||
'mailgun_api_key' => '',
|
||||
|
||||
/**
|
||||
* ID of the mailing list to send emails to.
|
||||
* API base URL including the sending domain. Make sure to include the
|
||||
* trailing slash.
|
||||
*
|
||||
* Example: uw3NSzkRMS
|
||||
* Example: https://api.mailgun.net/v3/
|
||||
*/
|
||||
'mailchimp_list_id' => '',
|
||||
'mailgun_base_url' => '',
|
||||
|
||||
/**
|
||||
* The specific newsletter to subscribe users to.
|
||||
*
|
||||
* Example: newsletter@app.beestat.io
|
||||
*/
|
||||
'mailgun_newsletter' => '',
|
||||
|
||||
/**
|
||||
* Auth ID for Smarty Streets address verification.
|
||||
|
@ -60,13 +60,9 @@ class ecobee extends external_api {
|
||||
);
|
||||
|
||||
$identifiers = [];
|
||||
$email_addresses = [];
|
||||
foreach($response['thermostatList'] as $thermostat) {
|
||||
$runtime = $thermostat['runtime'];
|
||||
$identifiers[] = $thermostat['identifier'];
|
||||
|
||||
$notification_settings = $thermostat['notificationSettings'];
|
||||
$email_addresses = array_merge($email_addresses, $notification_settings['emailAddresses']);
|
||||
}
|
||||
|
||||
// Look to see if any of the returned thermostats exist. This does not use
|
||||
@ -119,22 +115,6 @@ class ecobee extends external_api {
|
||||
else {
|
||||
$this->api('user', 'create_anonymous_user');
|
||||
$this->api('ecobee_token', 'create', ['attributes' => $ecobee_token]);
|
||||
|
||||
if(count($email_addresses) > 0) {
|
||||
try {
|
||||
$this->api(
|
||||
'mailchimp',
|
||||
'subscribe',
|
||||
[
|
||||
'email_address' => $email_addresses[0]
|
||||
]
|
||||
);
|
||||
} catch(Exception $e) {
|
||||
// Ignore failed subscribe exceptions since it's not critical to the
|
||||
// success of this. Everything is logged regardless.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Redirect to the proper location.
|
||||
|
@ -99,6 +99,7 @@ class ecobee_thermostat extends cora\crud {
|
||||
|
||||
// Loop over the returned thermostats and create/update them as necessary.
|
||||
$thermostat_ids_to_keep = [];
|
||||
$email_addresses = [];
|
||||
foreach($response['thermostatList'] as $api_thermostat) {
|
||||
$ecobee_thermostat = $this->get(
|
||||
[
|
||||
@ -169,6 +170,12 @@ class ecobee_thermostat extends cora\crud {
|
||||
]
|
||||
);
|
||||
|
||||
foreach($api_thermostat['notificationSettings']['emailAddresses'] as $email_address) {
|
||||
if(preg_match('/.+@.+\..+/', $email_address) === 1) {
|
||||
$email_addresses[] = trim(strtolower($email_address));
|
||||
}
|
||||
}
|
||||
|
||||
// Grab a bunch of attributes from the ecobee_thermostat and attach them
|
||||
// to the thermostat.
|
||||
$attributes = [];
|
||||
@ -260,6 +267,19 @@ class ecobee_thermostat extends cora\crud {
|
||||
);
|
||||
}
|
||||
|
||||
// Update the email_address on the user.
|
||||
if(count($email_addresses) > 0) {
|
||||
$email_address_counts = array_count_values($email_addresses);
|
||||
arsort($email_address_counts);
|
||||
$email_address = array_keys(array_slice($email_address_counts, 0, 1, true))[0];
|
||||
$this->api('user', 'update', [
|
||||
'attributes' => [
|
||||
'user_id' => $this->session->get_user_id(),
|
||||
'email_address' => $email_address
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// Inactivate any ecobee_thermostats that were no longer returned.
|
||||
$thermostats = $this->api('thermostat', 'read');
|
||||
$ecobee_thermostat_ids_to_return = [];
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* All external APIs (ecobee, SmartyStreets, Patreon, MailChimp) extend this
|
||||
* All external APIs (ecobee, SmartyStreets, Patreon, Mailgun) extend this
|
||||
* class. This provides a generic cURL function with a couple basic arguments,
|
||||
* and also logging.
|
||||
*
|
||||
@ -88,7 +88,10 @@ class external_api extends cora\api {
|
||||
|
||||
$this->curl_info = curl_getinfo($curl_handle);
|
||||
|
||||
if($curl_response === false || curl_errno($curl_handle) !== 0) {
|
||||
if(
|
||||
$curl_response === false ||
|
||||
curl_errno($curl_handle) !== 0
|
||||
) {
|
||||
// Error logging
|
||||
if($this::$log_mysql === 'all' || $this::$log_mysql === 'error') {
|
||||
$this->log_mysql($curl_response, true);
|
||||
@ -103,7 +106,6 @@ class external_api extends cora\api {
|
||||
'curl_error' => curl_error($curl_handle)
|
||||
]
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// General (success) logging
|
||||
|
@ -1,80 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* High level functionality for interacting with the Mailchimp API.
|
||||
*
|
||||
* @author Jon Ziebell
|
||||
*/
|
||||
class mailchimp extends external_api {
|
||||
|
||||
protected static $log_mysql = 'all';
|
||||
|
||||
protected static $cache = false;
|
||||
protected static $cache_for = null;
|
||||
|
||||
/**
|
||||
* Send an API call off to MailChimp
|
||||
*
|
||||
* @param string $method HTTP Method.
|
||||
* @param string $endpoint API Endpoint.
|
||||
* @param array $data API request data.
|
||||
*
|
||||
* @throws Exception If MailChimp did not return valid JSON.
|
||||
*
|
||||
* @return array The MailChimp response.
|
||||
*/
|
||||
private function mailchimp_api($method, $endpoint, $data) {
|
||||
$curl_response = $this->curl([
|
||||
'url' => 'https://us18.api.mailchimp.com/3.0/' . $endpoint,
|
||||
'post_fields' => json_encode($data, JSON_FORCE_OBJECT),
|
||||
'method' => $method,
|
||||
'header' => [
|
||||
'Authorization: Basic ' . base64_encode(':' . $this->setting->get('mailchimp_api_key')),
|
||||
'Content-Type: application/x-www-form-urlencoded'
|
||||
]
|
||||
]);
|
||||
|
||||
$response = json_decode($curl_response, true);
|
||||
|
||||
if ($response === null) {
|
||||
throw new Exception('Invalid JSON');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe an email address to the mailing list. This will only mark you
|
||||
* as "pending" so you have to click a link in the email to actually
|
||||
* subscribe.
|
||||
*
|
||||
* @param string $email_address The email address to subscribe.
|
||||
*
|
||||
* @throws Exception If subscribing to the mailing list fails for some
|
||||
* reason. For example, if already subscribed.
|
||||
*
|
||||
* @return array The MailChimp response.
|
||||
*/
|
||||
public function subscribe($email_address) {
|
||||
$method = 'POST';
|
||||
|
||||
$endpoint =
|
||||
'lists/' .
|
||||
$this->setting->get('mailchimp_list_id') .
|
||||
'/members/'
|
||||
;
|
||||
|
||||
$data = [
|
||||
'email_address' => $email_address,
|
||||
'status' => 'pending'
|
||||
];
|
||||
|
||||
$response = $this->mailchimp_api($method, $endpoint, $data);
|
||||
|
||||
if(isset($response['id']) === false) {
|
||||
throw new Exception('Could not subscribe to mailing list.');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
123
api/mailgun.php
Normal file
123
api/mailgun.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* High level functionality for interacting with the Mailgun API.
|
||||
*
|
||||
* @author Jon Ziebell
|
||||
*/
|
||||
class mailgun extends external_api {
|
||||
|
||||
protected static $log_mysql = 'all';
|
||||
|
||||
protected static $cache = false;
|
||||
protected static $cache_for = null;
|
||||
|
||||
public static $exposed = [
|
||||
'private' => [],
|
||||
'public' => [
|
||||
'subscribe',
|
||||
'unsubscribe'
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* Send an API call off to mailgun
|
||||
*
|
||||
* @param string $method HTTP Method.
|
||||
* @param string $endpoint API Endpoint.
|
||||
* @param array $data API request data.
|
||||
*
|
||||
* @throws Exception If mailgun did not return valid JSON.
|
||||
*
|
||||
* @return array The mailgun response.
|
||||
*/
|
||||
private function mailgun_api($method, $endpoint, $data) {
|
||||
$curl_response = $this->curl([
|
||||
'url' => $this->setting->get('mailgun_base_url') . $endpoint,
|
||||
'post_fields' => $data,
|
||||
'method' => $method,
|
||||
'header' => [
|
||||
'Authorization: Basic ' . base64_encode('api:' . $this->setting->get('mailgun_api_key')),
|
||||
'Content-Type: multipart/form-data'
|
||||
]
|
||||
]);
|
||||
|
||||
$response = json_decode($curl_response, true);
|
||||
|
||||
if ($response === null) {
|
||||
throw new cora\exception('Invalid JSON', 10600);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the mailing list.
|
||||
*
|
||||
* @param string $email_address The email address to subscribe.
|
||||
*
|
||||
* @throws exception If the subscribe failed.
|
||||
*
|
||||
* @return array Subscriber info.
|
||||
*/
|
||||
public function subscribe($email_address) {
|
||||
$method = 'POST';
|
||||
|
||||
$endpoint = 'lists/' . $this->setting->get('mailgun_newsletter') . '/members';
|
||||
|
||||
$data = [
|
||||
'address' => $email_address,
|
||||
'subscribed' => 'yes',
|
||||
'upsert' => 'yes'
|
||||
];
|
||||
|
||||
$response = $this->mailgun_api($method, $endpoint, $data);
|
||||
|
||||
if (
|
||||
isset($response['member']) &&
|
||||
isset($response['member']['address']) &&
|
||||
isset($response['member']['subscribed']) &&
|
||||
$response['member']['address'] === $email_address &&
|
||||
$response['member']['subscribed'] === true
|
||||
) {
|
||||
return $response['member'];
|
||||
} else {
|
||||
throw new cora\exception('Failed to subscribe.', 10601);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from the mailing list.
|
||||
*
|
||||
* @param string $email_address The email address to unsubscribe.
|
||||
*
|
||||
* @throws exception If the unsubscribe failed.
|
||||
*
|
||||
* @return array Subscriber info.
|
||||
*/
|
||||
public function unsubscribe($email_address) {
|
||||
$method = 'POST';
|
||||
|
||||
$endpoint = 'lists/' . $this->setting->get('mailgun_newsletter') . '/members';
|
||||
|
||||
$data = [
|
||||
'address' => $email_address,
|
||||
'subscribed' => 'no',
|
||||
'upsert' => 'yes'
|
||||
];
|
||||
|
||||
$response = $this->mailgun_api($method, $endpoint, $data);
|
||||
|
||||
if (
|
||||
isset($response['member']) &&
|
||||
isset($response['member']['address']) &&
|
||||
isset($response['member']['subscribed']) &&
|
||||
$response['member']['address'] === $email_address &&
|
||||
$response['member']['subscribed'] === false
|
||||
) {
|
||||
return $response['member'];
|
||||
} else {
|
||||
throw new cora\exception('Failed to unsubscribe.', 10602);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Cache for these external API calls.
|
||||
*
|
||||
* @author Jon Ziebell
|
||||
*/
|
||||
class mailchimp_api_cache extends external_api_cache {}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Cache for these external API calls.
|
||||
*
|
||||
* @author Jon Ziebell
|
||||
*/
|
||||
class mailgun_api_cache extends external_api_cache {}
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Log for these external API calls.
|
||||
*
|
||||
* @author Jon Ziebell
|
||||
*/
|
||||
class mailchimp_api_log extends external_api_log {}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Log for these external API calls.
|
||||
*
|
||||
* @author Jon Ziebell
|
||||
*/
|
||||
class mailgun_api_log extends external_api_log {}
|
@ -345,6 +345,7 @@ a.inverted:active {
|
||||
.icon.code_tags:before { content: "\F174"; }
|
||||
.icon.dots_vertical:before { content: "\F1D9"; }
|
||||
.icon.download:before { content: "\F1DA"; }
|
||||
.icon.email:before { content: "\F1EE"; }
|
||||
.icon.exit_to_app:before { content: "\F206"; }
|
||||
.icon.eye:before { content: "\F208"; }
|
||||
.icon.eye_off:before { content: "\F209"; }
|
||||
|
@ -164,21 +164,32 @@ beestat.api.prototype.load_ = function(response_text) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Special handling for these error codes.
|
||||
const error_codes = {
|
||||
'log_out': [
|
||||
1505, // Session is expired.
|
||||
10000, // Could not get first token.
|
||||
10001, // Could not refresh ecobee token; no token found.
|
||||
10002, // Could not refresh ecobee token; ecobee returned no token.
|
||||
10500, // Ecobee access was revoked by user.
|
||||
10501 // No ecobee access for this user.
|
||||
],
|
||||
'ignore': [
|
||||
10601 // Failed to subscribe.
|
||||
]
|
||||
};
|
||||
|
||||
// Error handling
|
||||
if (
|
||||
response.data &&
|
||||
(
|
||||
response.data.error_code === 1505 || // Session is expired.
|
||||
response.data.error_code === 10000 || // Could not get first token.
|
||||
response.data.error_code === 10001 || // Could not refresh ecobee token; no token found.
|
||||
response.data.error_code === 10002 || // Could not refresh ecobee token; ecobee returned no token.
|
||||
response.data.error_code === 10500 || // Ecobee access was revoked by user.
|
||||
response.data.error_code === 10501 // No ecobee access for this user.
|
||||
)
|
||||
error_codes.log_out.includes(response.data.error_code) === true
|
||||
) {
|
||||
window.location.href = '/';
|
||||
return;
|
||||
} else if (response.success !== true) {
|
||||
} else if (
|
||||
response.success !== true &&
|
||||
error_codes.ignore.includes(response.data.error_code) === false
|
||||
) {
|
||||
beestat.error(
|
||||
'API call failed: ' + response.data.error_message,
|
||||
JSON.stringify(response, null, 2)
|
||||
|
@ -34,7 +34,9 @@ beestat.setting = function(key, opt_value, opt_callback) {
|
||||
'comparison_region': 'global',
|
||||
'comparison_property_type': 'similar',
|
||||
|
||||
'temperature_unit': '°F'
|
||||
'temperature_unit': '°F',
|
||||
|
||||
'first_run': true
|
||||
};
|
||||
|
||||
if (user.settings === null) {
|
||||
|
@ -21,38 +21,39 @@ beestat.component.card.footer.prototype.decorate_contents_ = function(parent) {
|
||||
footer_links.appendChild(
|
||||
$.createElement('a')
|
||||
.setAttribute('href', 'https://doc.beestat.io/')
|
||||
.innerHTML('Help')
|
||||
.innerText('Help')
|
||||
);
|
||||
footer_links.appendChild($.createElement('span').innerHTML(' • '));
|
||||
footer_links.appendChild($.createElement('span').innerText(' • '));
|
||||
|
||||
footer_links.appendChild(
|
||||
$.createElement('a')
|
||||
.setAttribute('href', 'https://community.beestat.io/')
|
||||
.setAttribute('target', '_blank')
|
||||
.innerHTML('Feedback')
|
||||
.innerText('Feedback')
|
||||
);
|
||||
footer_links.appendChild($.createElement('span').innerHTML(' • '));
|
||||
footer_links.appendChild($.createElement('span').innerText(' • '));
|
||||
|
||||
footer_links.appendChild(
|
||||
$.createElement('a')
|
||||
.setAttribute('href', 'https://beestat.io/privacy/')
|
||||
.setAttribute('target', '_blank')
|
||||
.innerHTML('Privacy')
|
||||
.innerText('Privacy')
|
||||
);
|
||||
footer_links.appendChild($.createElement('span').innerHTML(' • '));
|
||||
footer_links.appendChild($.createElement('span').innerText(' • '));
|
||||
|
||||
footer_links.appendChild(
|
||||
$.createElement('a')
|
||||
.setAttribute('href', 'http://eepurl.com/dum59r')
|
||||
.setAttribute('target', '_blank')
|
||||
.innerHTML('Mailing List')
|
||||
.innerText('Newsletter')
|
||||
.addEventListener('click', function() {
|
||||
(new beestat.component.modal.newsletter()).render();
|
||||
})
|
||||
);
|
||||
footer_links.appendChild($.createElement('span').innerHTML(' • '));
|
||||
footer_links.appendChild($.createElement('span').innerText(' • '));
|
||||
|
||||
footer_links.appendChild(
|
||||
$.createElement('a')
|
||||
.setAttribute('href', 'mailto:contact@beestat.io')
|
||||
.innerHTML('Contact')
|
||||
.innerText('Contact')
|
||||
);
|
||||
|
||||
};
|
||||
|
@ -27,8 +27,7 @@ beestat.component.card.runtime_thermostat_detail = function(thermostat_id) {
|
||||
[
|
||||
'setting.runtime_thermostat_detail_range_type',
|
||||
'setting.runtime_thermostat_detail_range_dynamic',
|
||||
'cache.runtime_thermostat',
|
||||
'cache.thermostat'
|
||||
'cache.runtime_thermostat'
|
||||
],
|
||||
change_function
|
||||
);
|
||||
|
@ -63,7 +63,7 @@ beestat.component.input.text.prototype.decorate_ = function(parent) {
|
||||
parent.appendChild(icon_container);
|
||||
|
||||
this.input_.style({
|
||||
'padding-left': '24px'
|
||||
'padding-left': '28px'
|
||||
});
|
||||
|
||||
(new beestat.component.icon(this.icon_).set_size(16)
|
||||
|
131
js/component/modal/newsletter.js
Normal file
131
js/component/modal/newsletter.js
Normal file
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Newsletter
|
||||
*/
|
||||
beestat.component.modal.newsletter = function() {
|
||||
beestat.component.modal.apply(this, arguments);
|
||||
};
|
||||
beestat.extend(beestat.component.modal.newsletter, beestat.component.modal);
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.modal.newsletter.prototype.decorate_contents_ = function(parent) {
|
||||
parent.appendChild($.createElement('p').innerHTML('Interested in following beestat development? Subscribe to the newsletter for an updates. Emails are sparse; only a few every year.'));
|
||||
|
||||
this.email_address_ = new beestat.component.input.text()
|
||||
.set_style({
|
||||
'width': '100%',
|
||||
'max-width': '300px',
|
||||
'border-bottom': '2px solid ' + beestat.style.color.lightblue.base
|
||||
});
|
||||
|
||||
if (this.subscribed_ === true) {
|
||||
this.email_address_.set_icon('check');
|
||||
this.email_address_.disable();
|
||||
this.email_address_.set_value(this.state_.email_address_);
|
||||
} else if (this.subscribed_ === false) {
|
||||
this.email_address_.set_icon('email');
|
||||
this.email_address_.set_value(this.state_.email_address_);
|
||||
} else {
|
||||
this.email_address_.set_icon('email');
|
||||
this.email_address_.set_value(beestat.user.get().email_address);
|
||||
}
|
||||
|
||||
this.email_address_.render(parent);
|
||||
|
||||
if (this.subscribed_ === true) {
|
||||
parent.appendChild($.createElement('p').innerHTML('You are now subscribed to the beestat newsletter!'));
|
||||
} else if (this.subscribed_ === false) {
|
||||
parent.appendChild(
|
||||
$.createElement('p')
|
||||
.innerHTML(this.error_)
|
||||
.style('color', beestat.style.color.red.base)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get title.
|
||||
*
|
||||
* @return {string} Tht title.
|
||||
*/
|
||||
beestat.component.modal.newsletter.prototype.get_title_ = function() {
|
||||
return 'Newsletter';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the buttons that go on the bottom of this modal.
|
||||
*
|
||||
* @return {[beestat.component.button]} The buttons.
|
||||
*/
|
||||
beestat.component.modal.newsletter.prototype.get_buttons_ = function() {
|
||||
var self = this;
|
||||
|
||||
let buttons = [];
|
||||
if (this.subscribed_ === true) {
|
||||
const ok = new beestat.component.button()
|
||||
.set_background_color(beestat.style.color.green.base)
|
||||
.set_background_hover_color(beestat.style.color.green.light)
|
||||
.set_text_color('#fff')
|
||||
.set_text('Close')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
});
|
||||
buttons.push(ok);
|
||||
} else {
|
||||
const no_thanks = new beestat.component.button()
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_text('No Thanks')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
});
|
||||
buttons.push(no_thanks);
|
||||
|
||||
const subscribe = new beestat.component.button()
|
||||
.set_background_color(beestat.style.color.green.base)
|
||||
.set_background_hover_color(beestat.style.color.green.light)
|
||||
.set_text_color('#fff')
|
||||
.set_text('Subscribe')
|
||||
.addEventListener('click', function() {
|
||||
self.state_.email_address_ = self.email_address_.get_value();
|
||||
|
||||
if (self.state_.email_address_.match(/.+@.+\..+/) === null) {
|
||||
self.subscribed_ = false;
|
||||
self.error_ = 'Invalid email address.';
|
||||
self.rerender();
|
||||
return;
|
||||
}
|
||||
|
||||
this
|
||||
.set_background_color(beestat.style.color.gray.base)
|
||||
.set_background_hover_color()
|
||||
.removeEventListener('click');
|
||||
|
||||
no_thanks.removeEventListener('click');
|
||||
|
||||
new beestat.api()
|
||||
.add_call(
|
||||
'mailgun',
|
||||
'subscribe',
|
||||
{'email_address': self.state_.email_address_}
|
||||
)
|
||||
.set_callback(function(response) {
|
||||
if (response.subscribed === true) {
|
||||
self.subscribed_ = true;
|
||||
} else {
|
||||
self.subscribed_ = false;
|
||||
self.error_ = 'Subscribe failed; please try again later.';
|
||||
}
|
||||
self.rerender();
|
||||
})
|
||||
.send();
|
||||
});
|
||||
buttons.push(subscribe);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
};
|
@ -97,6 +97,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
|
||||
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/modal/newsletter.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;
|
||||
|
@ -225,7 +225,14 @@ beestat.layer.load.prototype.decorate_ = function(parent) {
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
/*
|
||||
* Show the first run modal or the announcements modal if there are unread
|
||||
* important announcements.
|
||||
*/
|
||||
if (beestat.setting('first_run') === true) {
|
||||
beestat.setting('first_run', false);
|
||||
(new beestat.component.modal.newsletter()).render();
|
||||
} else if (
|
||||
last_read_announcement_id === undefined ||
|
||||
(
|
||||
most_recent_important_announcement_id !== undefined &&
|
||||
@ -234,7 +241,6 @@ beestat.layer.load.prototype.decorate_ = function(parent) {
|
||||
) {
|
||||
(new beestat.component.modal.announcements()).render();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
api.send();
|
||||
|
Loading…
x
Reference in New Issue
Block a user