Browse Source

Refine UI.

pull/395/head
Bowen Ding 6 years ago
parent
commit
bf46947b26
  1. 115
      sigal/plugins/encrypt/static/decrypt.js
  2. 2
      sigal/themes/colorbox/templates/base.html
  3. 108
      sigal/themes/default/templates/decrypt.html
  4. 2
      sigal/themes/galleria/templates/base.html
  5. 2
      sigal/themes/photoswipe/templates/base.html

115
sigal/plugins/encrypt/static/decrypt.js

@ -30,15 +30,16 @@ class Decryptor {
if (Decryptor.isServiceWorker()) {
this._role = "service_worker";
} else if (!Decryptor.isWorker()) {
if (!Decryptor.featureTest()) {
alert("This page cannot function properly because your browser does not support some critical features or you are in private browsing mode. Please update your browser or exit private browsing mode.");
return;
}
this._role = "main";
this._config = config;
document.addEventListener(
"DOMContentLoaded",
(e) => {
if (!Decryptor.featureTest()) {
Decryptor.mSetUIVisibility("main-prompt", true);
Decryptor.mSetUIVisibility("missing-feature", true);
return;
}
const local_config = this._mGetLocalConfig();
if (local_config) {
this._config = local_config;
@ -53,11 +54,7 @@ class Decryptor {
}
static init(config) {
if (Decryptor.isServiceWorker()) {
self.decryptor = new Decryptor(config);
} else {
window.decryptor = new Decryptor(config);
}
self.decryptor = new Decryptor(config);
}
static featureTest() {
@ -131,11 +128,11 @@ class Decryptor {
}
static isInitialized() {
if (Decryptor.isServiceWorker()) {
return 'decryptor' in self && self.decryptor.workerReady;
} else {
return 'decryptor' in window && window.decryptor.workerReady;
}
return 'decryptor' in self;
}
static isWorkerReady() {
return Decryptor.isInitialized() && self.decryptor._workerReady;
}
get workerReady() {
@ -148,9 +145,12 @@ class Decryptor {
_mSetWorkerReady() {
this.workerReady = true;
const had_been_ready_before = this._mGetLocalConfig() !== null;
localStorage.setItem(this._config.galleryId, JSON.stringify(this._config));
if (!had_been_ready_before) {
Decryptor.mSetUIVisibility("main-prompt", false);
Decryptor.mSetUIVisibility("password-prompt", false);
Decryptor.mSetUIVisibility("incorrect-password", false);
const firstVisit = this._mGetLocalConfig() === null;
if (firstVisit) {
localStorage.setItem(this._config.galleryId, JSON.stringify(this._config));
window.location.reload();
}
}
@ -158,7 +158,10 @@ class Decryptor {
_mUnsetWorkerReady() {
this.workerReady = false;
localStorage.removeItem(this._config.galleryId);
alert("Incorrect password!");
Decryptor.mSetUIVisibility("main-prompt", true);
Decryptor.mSetUIVisibility("password-prompt", true);
Decryptor.mSetUIVisibility("incorrect-password", true);
Decryptor.mPlayUIAnimation("incorrect-password");
}
_mGetLocalConfig() {
@ -197,11 +200,28 @@ class Decryptor {
(e) => Decryptor.onMessage(this.serviceWorker, e);
this.serviceWorker = this._proxyWrap(this.serviceWorker);
if (!(await this.serviceWorker.Decryptor.isInitialized())) {
if (!('password' in this._config && this._config.password)) {
this._config.password = await this._mAskPassword();
if (!(await this.serviceWorker.Decryptor.isWorkerReady())) {
if ('password' in this._config && this._config.password) {
this.serviceWorker._swInitServiceWorker(this._config);
} else {
Decryptor.mSetUIVisibility("main-prompt", true);
Decryptor.mSetUIVisibility("password-prompt", true);
document.addEventListener(
"DecryptorPasswordProvided",
(e) => {
const password = e.detail;
if (password) {
this._config.password = password;
this.serviceWorker._swInitServiceWorker(this._config);
}
},
{ passive: true }
);
}
this.serviceWorker._swInitServiceWorker(this._config);
} else {
this.workerReady = true;
Decryptor.mSetUIVisibility("main-prompt", false);
Decryptor.mSetUIVisibility("password-prompt", false);
}
}
@ -221,18 +241,43 @@ class Decryptor {
}
}
/* main thread only */
async _mAskPassword() {
const config = this._mGetLocalConfig();
if (config && config.password) {
return config.password;
static async setPassword(password) {
Decryptor._sendEvent(document, "DecryptorPasswordProvided", password);
}
static mSetUIVisibility(UIElement, visible) {
let element;
switch (UIElement) {
case "password-prompt":
element = "decrypt-password-prompt";
break;
case "incorrect-password":
element = "indicator-text-incorrect-password";
break;
case "missing-feature":
element = "decrypt-missing-feature";
break;
case "main-prompt":
element = "decrypt-main-prompt";
break;
default:
return;
}
const password = prompt("Input password to view this gallery:");
if (password) {
this._config.password = password;
return password;
if (visible) {
document.getElementById(element).classList.remove("hidden");
} else {
return "__wrong_password__";
document.getElementById(element).classList.add("hidden");
}
}
static mPlayUIAnimation(UIElement) {
switch (UIElement) {
case "incorrect-password":
const element = document.getElementById("indicator-text-incorrect-password").parentElement;
element.classList.add("shake-animated");
break;
default:
return;
}
}
@ -507,8 +552,8 @@ class Decryptor {
}
console.debug(`Fetch succeeded with encrypted image ${request.url}, trying to decrypt`);
if (!Decryptor.isInitialized()) {
if ('decryptor' in self) {
if (!Decryptor.isWorkerReady()) {
if (Decryptor.isInitialized()) {
try{
const client = await self.clients.get(e.clientId);
const config = await self.decryptor._proxyWrap(client)._mGetLocalConfig();
@ -517,7 +562,7 @@ class Decryptor {
// do nothing
}
}
if (!Decryptor.isInitialized()) {
if (!Decryptor.isWorkerReady()) {
console.debug(`Decryptor not initialized on fetch event`);
return Decryptor.imageErrorResponse.clone();
}

2
sigal/themes/colorbox/templates/base.html

@ -13,7 +13,6 @@
<link rel="stylesheet" href="{{ theme.url }}/css/style.css">
{% block extra_head %}{% endblock extra_head %}
{% include 'analytics.html' %}
{% include 'decrypt.html' %}
</head>
<body>
{% include 'gtm.html' %}
@ -50,5 +49,6 @@
</div>
{% block footer %}{% endblock %}
{% include 'piwik.html' %}
{% include 'decrypt.html' %}
</body>
</html>

108
sigal/themes/default/templates/decrypt.html

@ -1,13 +1,97 @@
{% if 'sigal.plugins.encrypt' is in settings.plugins %}
<script src="{{ theme.url }}/decrypt.js"></script>
<script>
Decryptor.init({
password: "{{ encrypt_options.filtered_password }}",
sw_script: "{{ theme.url }}/../sw.js",
galleryId: "{{ encrypt_options.galleryId }}",
gcm_tag: "{{ encrypt_options.escaped_gcm_tag }}",
kdf_salt: "{{ encrypt_options.escaped_kdf_salt }}",
kdf_iters: {{ encrypt_options.kdf_iters }}
});
</script>
{% if 'sigal.plugins.encrypt' is in settings.plugins %}
<script src="{{ theme.url }}/decrypt.js"></script>
<script>
Decryptor.init({
password: "{{ encrypt_options.filtered_password }}",
sw_script: "{{ theme.url }}/../sw.js",
galleryId: "{{ encrypt_options.galleryId }}",
gcm_tag: "{{ encrypt_options.escaped_gcm_tag }}",
kdf_salt: "{{ encrypt_options.escaped_kdf_salt }}",
kdf_iters: {{ encrypt_options.kdf_iters }}
});
</script>
<style>
.decrypt-fixed-prompt {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: inherit;
}
.decrypt-prompt-panel {
width: 100%;
height: 100%;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
text-align: center;
}
.decrypt-error-indicator {
color: red;
transform: translateX(0);
}
.hidden {
display: none !important;
}
.shake-animated {
animation: 0.1s ease-in-out 0s 2 normal shake;
}
@keyframes shake {
0% {transform: translateX(0px);}
25% {transform: translateX(-5px);}
50% {transform: translateX(0px);}
75% {transform: translateX(5px);}
100% {transform: translateX(0px);}
}
.close-marker {
position: absolute;
top: 2rem;
right: 2rem;
width: 2rem;
height: 2rem;
cursor: pointer;
background-color: inherit;
}
.close-marker-line {
width:2rem;
height: 2px;
background-color: inherit;
position: absolute;
top: 1rem;
left: 0;
filter: invert(1);
}
</style>
<div class="decrypt-fixed-prompt hidden" id="decrypt-main-prompt">
<div id="decrypt-close-marker" class="close-marker" onclick="this.parentElement.classList.add('hidden')">
<div class="close-marker-line" style="transform: rotate(45deg);"></div>
<div class="close-marker-line" style="transform: rotate(-45deg);"></div>
</div>
<div class="decrypt-prompt-panel hidden" id="decrypt-password-prompt">
<h1>Private Gallery: {{ index_title }}</h1>
<p>Password is required to access this gallery:</p>
<form action="#" onsubmit="Decryptor.setPassword(document.getElementById('decrypt-password-input').value); return false;">
<input id="decrypt-password-input" placeholder="Password" type="text" />
<button id="decrypt-password-enter">Enter</button>
</form>
<p class="decrypt-error-indicator" onanimationend="this.classList.remove('shake-animated')">&nbsp;
<span class="hidden" id="indicator-text-incorrect-password">Incorrect password!</span>
</p>
</div>
<div class="decrypt-prompt-panel hidden" id="decrypt-missing-feature">
<h1>Private Gallery: {{ index_title }}</h1>
<p>Password is required to access this gallery:</p>
<p class="decrypt-error-indicator">
This page cannot function properly because some features are not available.
</p>
<p>Some possible solutions are:</p>
<ul>
<li>You are in private browsing mode. Try switching to normal mode.</li>
<li>This page is not loaded from a HTTPS connection. Reload with HTTPS.</li>
<li>Your browser is outdated. Consider upgrading to a latest version.</li>
</ul>
</div>
</div>
{% endif %}

2
sigal/themes/galleria/templates/base.html

@ -14,7 +14,6 @@
<link rel="stylesheet" href="{{ theme.url }}/css/style.css">
{% block extra_head %}{% endblock extra_head %}
{% include 'analytics.html' %}
{% include 'decrypt.html' %}
</head>
<body>
{% include 'gtm.html' %}
@ -36,5 +35,6 @@
</div>
{% block late_js %}{% endblock late_js %}
{% include 'piwik.html' %}
{% include 'decrypt.html' %}
</body>
</html>

2
sigal/themes/photoswipe/templates/base.html

@ -11,7 +11,6 @@
{% block extra_head %}{% endblock extra_head %}
<link rel="stylesheet" href="{{ theme.url }}/styles.css">
{% include 'analytics.html' %}
{% include 'decrypt.html' %}
</head>
<body>
{% include 'gtm.html' %}
@ -35,5 +34,6 @@
{% block extra_footer %}{% endblock %}
</div>
{% include 'piwik.html' %}
{% include 'decrypt.html' %}
</body>
</html>

Loading…
Cancel
Save