Merge branch 'loading-screen' into 2025.9-test

This commit is contained in:
yflory 2025-10-02 17:32:14 +02:00
commit fae1faa40a
11 changed files with 248 additions and 141 deletions

View File

@ -7,27 +7,36 @@
// text #3F4141
define([
'/customize/messages.js',
'/customize/lucide.js',
'less!/customize/src/less2/include/loading.less'
], function (Messages) {
], function (Messages, Lucide) {
var urlArgs = window.location.href.replace(/^.*\?([^\?]*)$/, function (all, x) { return x; });
var elem = document.createElement('div');
elem.setAttribute('id', 'cp-loading');
elem.innerHTML = [
'<div class="cp-loading-logo">',
'<img class="cp-loading-cryptofist" src="/api/logo?' + urlArgs + '" alt="" aria-hidden="true">',
'</div>',
'<div class="cp-loading-container">',
'<div class="cp-loading-spinner-container">',
'<span class="cp-spinner-main"></span>',
'</div>',
'<div class="cp-loading-progress" aria-hidden="true" role="presentation">',
'<div class="cp-loading-progress-list"></div>',
'<div class="cp-loading-progress-container"></div>',
'</div>',
'<p id="cp-loading-message"></p>',
'</div>'
].join('');
const logoPath = '/customize/CryptPad_logo_grey.svg';// XXX custom
elem.innerHTML = `
<div></div>
<div class="cp-loading-container">
<div class="cp-loading-progress" aria-hidden="true" role="presentation">
<div class="cp-loading-progress-list"></div>
<div class="cp-loading-progress-container"></div>
</div>
<div class="cp-loading-spinner-container">
<div class="cp-spinner-main"></div>
</div>
<p id="cp-loading-message"></p>
</div>
<div id="cp-loading-footer">
<div class="cp-loading-logo">
<img class="cp-loading-cryptofist" src="${logoPath}?${urlArgs}" alt="" aria-hidden="true"><span>CryptPad</span>
</div>
<div id="cp-loading-status">
<i data-lucide="lock" aria-hidden="true"></i>
<span>${Messages.loading_encrypted}</span>
</div>
</div>
`;
var built = false;
var types = ['less', 'drive', 'migrate', 'sf', 'team', 'pad', 'end']; // Msg.loading_state_0, loading_state_1, loading_state_2, loading_state_3, loading_state_4, loading_state_5
@ -35,6 +44,10 @@ define([
var makeList = function (data) {
var c = types.indexOf(data.type);
current = c;
const msg = Messages['loading_state_'+c];
return `<span>${msg}</span>`;
/*
var getLi = function (i) {
var check = (i < c || (i === c && data.progress >= 100)) ? 'square-check'
: 'square';
@ -52,6 +65,7 @@ define([
});
list += '</ul>';
return list;
*/
};
var makeBar = function (data) {
var c = types.indexOf(data.type);
@ -100,7 +114,10 @@ define([
if (el2) { el2.innerHTML = makeList(data); }
var el3 = document.querySelector('.cp-loading-progress-container');
if (el3) { el3.innerHTML = makeBar(data); }
var el4 = document.querySelector('#cp-loading-status');
if (el4) { el4.setAttribute('style', ''); }
} catch (e) {
console.error(e);
}
};
window.CryptPad_updateLoadingProgress = updateLoadingProgress;
@ -134,6 +151,7 @@ define([
if (!document.body) { return; }
clearInterval(intr);
document.body.appendChild(elem);
Lucide.createIcons();
};
intr = setInterval(append, 100);
append();

View File

@ -159,6 +159,8 @@ define(req, function(AppConfig, Default, Language) {
Messages.color7 = 'Blue';
Messages.color8 = 'Purple';
Messages.loading_encrypted = "end-to-end encrypted";
return Messages;
});

View File

@ -3,21 +3,28 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
(function () {
var logoPath = '/customize/CryptPad_logo.svg';
var logoPath = '/customize/CryptPad_logo_grey.svg';
if (location.pathname === '/' || location.pathname === '/index.html') {
logoPath = '/api/logo';
}
var elem = document.createElement('div');
elem.setAttribute('id', 'placeholder');
elem.innerHTML = [
'<div class="placeholder-logo-container">',
'<img class="placeholder-logo" alt="" aria-hidden="true" src="' + logoPath + '">',
'</div>',
'<div class="placeholder-message-container">',
'<p>Loading...</p>',
'</div>'
].join('');
elem.innerHTML = `
<div></div>
<div class="placeholder-message-container">
<p>Loading...</p>
</div>
<div id="placeholder-loading-footer">
<div class="placeholder-logo-container">
<img class="placeholder-logo" alt="" aria-hidden="true" src="${logoPath}"><span>CryptPad</span>
</div>
<div id="placeholder-loading-status">
<i data-lucide="lock" aria-hidden="true"></i>
<span>End-to-end encrypted</span>
</div>
</div>
`;
var key = 'CRYPTPAD_STORE|colortheme'; // handle outer
if (localStorage[key] && localStorage[key] === 'dark') {

View File

@ -66,6 +66,7 @@
@cryptpad_color_red_fader: fade(@cryptpad_color_red, 15%);
@cryptpad_color_warn_red: @cryptpad_color_red_fade;
@cryptpad_color_dark_red: #9e0000;
@cryptpad_color_darker_red: darken(@cryptpad_color_dark_red, 15%);
@cryptpad_color_mid_red: #FF8880;
@cryptpad_color_light_red: #FFD4D4;
@cryptpad_color_light_red_fade: fade(@cryptpad_color_light_red, 20%);
@ -119,12 +120,13 @@
// Loading screen
@cp_loading-bg: @cryptpad_color_grey_900;
@cp_loading-fg: @cryptpad_text_col;
@cp_loading-color: @cryptpad_color_grey_400;
@cp_loading-msg-bg: @cryptpad_color_grey_700;
@cp_loading-link: @cryptpad_color_brand_300;
@cp_loading-error-bg: @cryptpad_color_warn_red;
@cp_loading-error-fg: @cryptpad_text_col;
@cp_loading-progress-bg: @cryptpad_color_grey_800;
@cp_loading-progress-bar-bg: @cryptpad_color_brand;
@cp_loading-progress-bar-bg: @cryptpad_color_brand_300;
@cp_loading-spinner: @cryptpad_color_grey_600;
// Chat
@ -157,7 +159,7 @@
@cp_alerts-warning-bg: @cryptpad_color_yellow_fader;
@cp_alerts-warning-fg: @cryptpad_color_light_yellow;
@cp_alerts-warning-text: @cryptpad_color_light_yellow;
@cp_alerts-danger-bg: @cryptpad_color_red_fader;
@cp_alerts-danger-bg: @cryptpad_color_darker_red;
@cp_alerts-danger-fg: @cryptpad_color_light_red;
@cp_alerts-danger-text: @cryptpad_color_light_red;
@cp_alerts-info-bg: @cryptpad_color_brand_fadest;

View File

@ -66,6 +66,7 @@
@cryptpad_color_red_fader: fade(@cryptpad_color_red, 15%);
@cryptpad_color_warn_red: @cryptpad_color_red_fade;
@cryptpad_color_dark_red: #9e0000;
@cryptpad_color_darker_red: darken(@cryptpad_color_dark_red, 10%);
@cryptpad_color_mid_red: #FF8880;
@cryptpad_color_light_red: #FFD4D4;
@cryptpad_color_light_red_fade: fade(@cryptpad_color_light_red, 75%);
@ -118,12 +119,13 @@
// Loading screen
@cp_loading-bg: @cryptpad_color_grey_200;
@cp_loading-fg: @cryptpad_text_col;
@cp_loading-color: @cryptpad_color_grey_700;
@cp_loading-msg-bg: @cryptpad_color_white;
@cp_loading-link: @cryptpad_color_brand;
@cp_loading-error-bg: @cryptpad_color_warn_red;
@cp_loading-error-fg: @cryptpad_text_col;
@cp_loading-progress-bg: @cryptpad_color_white;
@cp_loading-progress-bar-bg: @cryptpad_color_brand;
@cp_loading-progress-bar-bg: @cryptpad_color_brand_300;
@cp_loading-spinner: @cryptpad_color_grey_500;
// Chat
@ -156,9 +158,9 @@
@cp_alerts-warning-bg: @cryptpad_color_yellow_fade;
@cp_alerts-warning-fg: @cryptpad_color_light_yellow;
@cp_alerts-warning-text: darken(@cp_alerts-warning-fg, 55%);
@cp_alerts-danger-bg: @cryptpad_color_light_red_fade;
@cp_alerts-danger-bg: @cryptpad_color_light_red;
@cp_alerts-danger-fg: @cryptpad_color_light_red;
@cp_alerts-danger-text: darken(@cp_alerts-danger-fg, 55%);
@cp_alerts-danger-text: @cryptpad_color_darker_red;
@cp_alerts-info-bg: fade(@cryptpad_color_brand, 15%);
@cp_alerts-info-text: @cryptpad_color_brand;
@cp_alerts-info-fg: @cryptpad_color_brand;

View File

@ -37,7 +37,7 @@
opacity: 1;
display: flex;
flex-flow: column;
justify-content: center;
justify-content: space-between;
align-items: center;
font: 20px 'Open Sans', 'Helvetica Neue', sans-serif !important;
&.cp-loading-transparent {
@ -49,23 +49,27 @@
transition: opacity 0.75s, visibility 0s 0.75s;
}
.cp-loading-logo {
height: 300px;
width: 300px;
margin-top: 50px;
flex: 0 1 auto;
min-height: 0;
text-align: center;
}
.cp-loading-logo img {
max-width: 100%;
max-height: 100%;
display: flex;
align-items: center;
gap: 1rem;
color: @cp_loading-spinner;
img {
margin: 0;
max-height: 60px;
}
span {
font-size: 40px;
font-family: "IBM Plex Mono";
.tools_unselectable();
}
}
.cp-loading-container {
width: 700px;
max-width: 90vw;
min-height: 236px;
max-height: calc(100vh - 20px);
margin: 50px;
flex-shrink: 0;
display: flex;
flex-flow: column;
@ -84,30 +88,45 @@
@media screen and (max-width: 500px) {
font-size: 16px !important;
.cp-loading-container {
height: 206px;
}
}
@media screen and (max-height: 700px) {
font-size: 16px !important;
.cp-loading-container {
height: 206px;
}
}
@media screen and (max-height: 500px) {
@media screen and (max-width: 300px) {
.cp-loading-logo {
display: none;
img {
max-height: 40px;
}
span {
font-size: 20px;
}
}
}
@media screen and (max-height: 600px) {
font-size: 16px !important;
}
#cp-loading-message {
background: @cp_loading-msg-bg;
padding: 20px;
padding: 1rem;
width: 100%;
border-radius: @variables_radius;
color: @cp_loading-fg;
text-align: left;
display: none;
overflow-y: auto;
&.cp-error-message, &.cp-error-message-alt {
margin: 0;
font-size: 16px;
padding: 0.5rem;
width: auto;
}
&.cp-error-message {
background-color: @cp_alerts-danger-bg;
color: @cp_alerts-danger-text;
}
&.cp-error-message-alt {
background-color: @cp_alerts-danger-text;
color: @cp_alerts-danger-bg;
}
&:empty {
display: none;
}
a {
color: @cp_loading-link;
border-radius: @variables_radius;
@ -116,13 +135,34 @@
margin-bottom: 0;
}
}
#cp-loading-status {
display: flex;
color: @cp_loading-color;
align-items: center;
font-family: "IBM Plex Mono";
padding-top: 0.5rem;
gap: 0.5rem;
svg {
margin: 0;
}
}
#cp-loading-footer {
margin-bottom: 2rem;
display: flex;
flex-flow: column;
align-items: center;
}
#cp-loading-password-prompt {
p.cp-password-error {
color: @cp_loading-error-fg;
background: @cp_loading-error-bg;
padding: 5px;
margin-bottom: 15px;
margin: 0;
margin-bottom: 0.5rem;
font-size: 16px;
padding: 0.5rem;
background-color: @cp_alerts-danger-bg;
color: @cp_alerts-danger-text;
border-radius: @variables_radius;
}
.cp-password-form {
display: flex;
@ -130,7 +170,7 @@
gap:0.5rem;
width: 100%;
.cp-password-container {
flex-shrink: 1;
flex: 1;
min-width: 0;
}
.cp-password-reveal {
@ -152,14 +192,9 @@
p.cp-password-info {
text-align: left;
margin-bottom: 15px;
margin-bottom: 0.5rem;
}
.cp-loading-spinner-container {
position: relative;
height: 80px;
margin-bottom: 50px;
}
.cp-loading-progress {
width: 100%;
text-align: center;
@ -170,39 +205,23 @@
text-overflow: ellipsis;
}
.cp-loading-progress-list {
text-align: left;
display: inline-block;
margin-bottom: 50px;
max-width: 100%;
ul {
list-style: none;
padding-left: 0;
margin: 0;
}
li {
padding: 0px 5px;
.tools_unselectable();
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
span {
margin-left: 10px;
&.percent {
position: absolute;
}
}
}
color: @cp_loading-color;
}
.cp-loading-progress-bar {
height: 24px;
margin: 1rem 0;
height: 5px;
background: @cp_loading-progress-bg;
border: 1px solid @cp_loading-progress-bar-bg;
border: 0;
//border: 1px solid @cp_loading-progress-bar-bg;
border-radius: @variables_radius;
}
.cp-loading-progress-bar-value {
height: 100%;
background: @cp_loading-progress-bar-bg;
border-radius: @variables_radius;
}
}
@ -216,17 +235,36 @@
}
}
.cp-spinner-main {
display: inline-block;
box-sizing: border-box;
width: 80px;
height: 80px;
border: 11px solid @cp_loading-spinner;
border-radius: 50%;
border-top-color: transparent;
animation: spin infinite 3s;
animation-timing-function: cubic-bezier(.6,0.15,0.4,0.85);
.cp-loading-spinner-container {
margin: 1rem 0;
height: 5px;
width: 100%;
border: 0;
overflow: hidden;
background: @cp_loading-progress-bg;
border-radius: @variables_radius;
}
.cp-spinner-main {
width: 100%;
height: 5px;
background: @cp_loading-progress-bar-bg;
border-radius: @variables_radius;
animation: loading-animation 1s infinite linear;
transform-origin: 0% 50%;
}
@keyframes loading-animation {
0% {
transform: translateX(0) scaleX(0);
}
40% {
transform: translateX(0) scaleX(0.4);
}
100% {
transform: translateX(100%) scaleX(0.5);
}
}
button {
.cp-spinner {

View File

@ -4,6 +4,23 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 500;
src: url("/customize/fonts/IBMPlexMono-Medium.woff2") format("woff2"), url("/customize/fonts/IBMPlexMono-Medium.woff") format("woff"); }
@font-face {
font-family: 'Open Sans';
src: url('/components/open-sans-fontface/fonts/Regular/OpenSans-Regular.eot');
src: url('/components/open-sans-fontface/fonts/Regular/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),
url('/components/open-sans-fontface/fonts/Regular/OpenSans-Regular.woff') format('woff'),
url('/components/open-sans-fontface/fonts/Regular/OpenSans-Regular.ttf') format('truetype'),
url('/components/open-sans-fontface/fonts/Regular/OpenSans-Regular.svg#OpenSansLight') format('svg');
font-weight: 300;
font-style: normal;
}
.cp-app-noscroll body {
background: transparent;
}
@ -21,61 +38,75 @@
left: 0px;
right: 0px;
background-color: #EEEEEE; /* @cp_loading-bg */
color: #424242; /* @cp_loading-fg */
color: #757575; /* grey_600 */
font-size: 1.3em;
line-height: 120%;
opacity: 1;
display: flex;
flex-flow: column;
justify-content: center;
justify-content: space-between;
align-items: center;
font: 20px 'Helvetica Neue', sans-serif !important;
font: 20px 'Open Sans', sans-serif !important;
}
html:not(.cp-app-noscroll) #placeholder.dark-theme {
html #placeholder.dark-theme {
background-color: #212121; /* @cp_loading-bg (dark) */
}
#placeholder.dark-theme {
color: #EEEEEE; /* @cp_loading-fg (dark) */
color: #BDBDBD; /* grey_400 */
}
#placeholder .placeholder-logo-container {
height: 300px;
width: 300px;
margin-top: 50px;
flex: 0 1 auto;
min-height: 0;
text-align: center;
opacity: 0;
animation: fadein 5s ease 2s forwards;
display: flex;
align-items: center;
gap: 1rem;
}
#placeholder .placeholder-logo-container img {
max-width: 100%;
max-height: 100%;
margin: 0;
max-height: 60px;
}
#placeholder .placeholder-logo-container span {
font-size: 40px;
font-family: "IBM Plex Mono";
user-select: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
cursor: pointer;
}
#placeholder .placeholder-message-container {
width: 700px;
max-width: 90vw;
height: 236px;
height: auto;
max-height: calc(100vh - 20px);
margin: 50px;
flex-shrink: 0;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
opacity: 0;
animation: fadein 5s ease 2s forwards;
}
#placeholder .placeholder-message-container p {
margin-top: 0;
}
#placeholder .placeholder-logo {
margin-left: auto;
margin-right: auto;
max-width: 90vw;
max-height: max(40vh, 250px);
width: auto;
height: auto;
margin-bottom: 2em;
#placeholder-loading-status {
font-size: 20px;
padding-top: 0.5rem;
font-family: "IBM Plex Mono";
}
#placeholder-loading-footer {
margin-bottom: 2rem;
display: flex;
flex-flow: column;
align-items: center;
flex: 0 1 auto;
min-height: 0;
opacity: 0;
animation: fadein 5s ease 2s forwards;
}
@keyframes fadein {
@ -87,22 +118,19 @@ html:not(.cp-app-noscroll) #placeholder.dark-theme {
#placeholder {
font-size: 16px !important;
}
#placeholder .placeholder-message-container {
height: 206px;
}
@media screen and (max-width: 300px) {
#placeholder .placeholder-logo-container img {
max-height: 40px;
}
#placeholder .placeholder-logo-container span {
font-size: 20px;
}
}
@media screen and (max-height: 700px) {
@media screen and (max-height: 600px) {
#placeholder {
font-size: 16px !important;
}
#placeholder .placeholder-message-container {
height: 206px;
}
}
@media screen and (max-height: 500px) {
#placeholder .placeholder-logo-container {
display: none;
}
}
:is(div, noscript) > p.noscript {
font-family: sans-serif;

View File

@ -1082,10 +1082,12 @@ define([
$('.cp-loading-spinner-container').show();
}
// Add loading text
const $message = $('#' + LOADING).find('#cp-loading-message');
$message.removeClass('cp-error-message cp-error-message-alt');
if (loadingText) {
$('#' + LOADING).find('#cp-loading-message').show().text(loadingText);
$message.show().text(loadingText);
} else {
$('#' + LOADING).find('#cp-loading-message').hide().text('');
$message.hide().text('');
}
};
if ($('#' + LOADING).length) {
@ -1124,7 +1126,7 @@ define([
$loading.find('.cp-loading-logo').hide();
$loading.append(content);
};
UI.errorLoadingScreen = function (error, transparent, exitable) {
UI.errorLoadingScreen = function (error, transparent, exitable, errorCls) {
if (error === 'Error: XDR encoding failure') {
console.warn(error);
return;
@ -1143,11 +1145,19 @@ define([
// Add the error message
var $error = $loading.find('#cp-loading-message').show();
$error.removeClass('cp-error-message cp-error-message-alt');
if (error instanceof Element) {
$error.html('').append(error);
} else {
errorCls = true;
$error.html(error || Messages.error);
}
if (errorCls) {
const cls = transparent ? 'cp-error-message-alt'
: 'cp-error-message';
$error.addClass(cls);
}
$error.find('a[href]').click(function (e) {
e.preventDefault();
var href = $(this).prop('href');
@ -1704,7 +1714,7 @@ define([
var input = split[1]; // User/admin manual input
var text = UI.getDestroyedPlaceholderMessage(code, isAccount);
var reasonBlock = input ? h('p', Messages._getKey('dph_reason', [input])) : undefined;
return h('div', [
return h('div.cp-loading-error', [
h('p', text),
reasonBlock
]);

View File

@ -3209,7 +3209,7 @@ define([
}
if (err.message && err.drive) {
let msg = UI.getDestroyedPlaceholder(err.message, true);
let msg = UI.getDestroyedPlaceholder(err.message, true, false, true);
return UI.errorLoadingScreen(msg, false, () => {
// When closing error screen
if (err.message === 'PASSWORD_CHANGE') {
@ -3221,7 +3221,7 @@ define([
if (err.message && (err.message !== "PASSWORD_CHANGE" || viewer)) {
// If readonly, tell the viewer that their link won't work with the new password
UI.errorLoadingScreen(UI.getDestroyedPlaceholder(err.message, false),
exitable, exitable);
exitable, exitable, true);
return;
}

View File

@ -8,7 +8,7 @@ try {
var theme = req.theme;
var os = req.themeOS;
window.CryptPad_theme = theme || os;
if ((theme || os) === 'dark') {
if ((theme || os) === 'dark') {
var s = document.createElement('style');
s.innerHTML = 'body { background: black; }';
document.body.appendChild(s);

View File

@ -939,7 +939,7 @@ define([
}
UI.errorLoadingScreen(msg, false, function () {
funcs.gotoURL('/drive/');
});
}, true);
});
ctx.sframeChan.on('EV_UNIVERSAL_EVENT', function (obj) {