Further improve the remote font intergation: Better preload strategy, better loading and UI interation.

This commit is contained in:
NI
2019-12-13 14:35:23 +08:00
parent a5696d6b63
commit c018c7b4be
12 changed files with 223 additions and 78 deletions

View File

@@ -212,6 +212,15 @@
</button>
</div>
</fieldset>
<div
v-if="preloaderIDName.length > 0"
style="width: 1px; height: 1px; margin: 10px; position: absolute; top: 0; bottom: 0; overflow: hidden;"
>
<div :id="preloaderIDName">
{{ current.title || connector.name }} wizard
</div>
</div>
</form>
</template>
@@ -219,6 +228,8 @@
import "./connector.css";
import * as command from "../commands/commands.js";
const preloaderIDPrefix = "connector-resource-preload-control-";
function buildField(i, field) {
return {
verified: false,
@@ -267,6 +278,7 @@ export default {
currentConnector: null,
currentConnectorCloseWait: null,
current: buildEmptyCurrent(),
preloaderIDName: "",
working: false,
disabled: false,
cancelled: false
@@ -399,6 +411,13 @@ export default {
throw new Error("Cannot run wizard multiple times");
}
this.preloaderIDName =
preloaderIDPrefix +
this.getConnector()
.wizard.control()
.ui()
.toLowerCase();
this.currentConnectorCloseWait = (async () => {
while (!this.disabled) {
let next = this.buildCurrent(await this.getConnector().wizard.next());

View File

@@ -21,14 +21,18 @@
@import "~hack-font/build/web/hack.css";
#home-content > #home-content-preload-drop::before {
#connector-resource-preload-control-console {
font-family: Hack;
}
#connector-resource-preload-control-console::after {
content: " ";
font-family: Hack, monospace;
font-family: Hack;
font-weight: bold;
}
#home-content > #home-content-preload-drop::after {
#connector-resource-preload-control-console::before {
content: " ";
font-family: Hack, monospace;
font-family: Hack;
font-style: italic;
}
#home-content > .screen > .screen-screen > .screen-console {
@@ -144,5 +148,32 @@
}
#home-content > .screen > .screen-screen > .screen-console > .console-console {
font-family: Hack, monospace;
display: flex;
flex-direction: column;
justify-content: center;
justify-items: center;
color: #fff;
}
#home-content
> .screen
> .screen-screen
> .screen-console
> .console-console
> .console-loading {
text-align: center;
font-size: 1em;
font-weight: lighter;
}
#home-content
> .screen
> .screen-screen
> .screen-console
> .console-console
> .console-loading
> .console-loading-icon {
background: url(./busy.svg) 50% no-repeat;
width: 100%;
height: 100px;
}

View File

@@ -22,8 +22,16 @@
<div
class="console-console"
style="top: 0; right: 0; left: 0; bottom: 0; padding 0; margin: 0; z-index: 0; position: absolute; overflow: hidden"
:style="'font-family: ' + typeface"
>
<h2 style="display:none;">Console</h2>
<div class="console-loading">
<div class="console-loading-icon"></div>
<div class="console-loading-message">
Initializing console ...
</div>
</div>
</div>
<!--
@@ -91,7 +99,13 @@ import "xterm/css/xterm.css";
const termTypeFace = "Hack";
const termFallbackTypeFace = "monospace";
const termTypeFaceLoadTimeout = 10000;
const termTypeFaceLoadTimeout = 3000;
const termTypeFaceLoadError =
'Remote font "' +
termTypeFace +
'" is unavailable, using "' +
termFallbackTypeFace +
'" instead until the remote font is loaded';
const termDefaultFontSize = 16;
const termMinFontSize = 14;
const termMaxFontSize = 36;
@@ -205,7 +219,11 @@ class Term {
});
}
open(root, callbacks) {
setFont(value) {
this.term.setOption("fontFamily", value);
}
init(root, callbacks) {
this.term.open(root);
this.term.textarea.addEventListener("focus", callbacks.focus);
@@ -248,32 +266,6 @@ class Term {
this.refit();
}
init(root, callbacks) {
const self = this;
return Promise.all([
new FontFaceObserver(termTypeFace).load(null, termTypeFaceLoadTimeout),
new FontFaceObserver(termTypeFace, { weight: "bold" }).load(
null,
termTypeFaceLoadTimeout
)
])
.then(() => {
self.open(root, callbacks);
})
.catch(() => {
callbacks.warn(
"Unable to load remote font, using " +
termFallbackTypeFace +
" instead"
);
self.term.setOption("fontFamily", termFallbackTypeFace);
self.open(root, callbacks);
});
}
dispatch(event) {
try {
this.term.textarea.dispatchEvent(event);
@@ -388,6 +380,8 @@ export default {
return {
screenKeys: consoleScreenKeys,
term: new Term(this.control),
typeface: termTypeFace,
running: true,
runner: null
};
},
@@ -407,19 +401,87 @@ export default {
}
},
async mounted() {
this.running = true;
await this.init();
},
beforeDestroy() {
this.deinit();
this.running = false;
},
methods: {
loadRemoteFont(typeface, timeout) {
return Promise.all([
new FontFaceObserver(typeface).load(null, timeout),
new FontFaceObserver(typeface, {
weight: "bold"
}).load(null, timeout)
]);
},
retryLoadRemoteFont(typeface, timeout, onSuccess) {
const self = this;
self
.loadRemoteFont(typeface, timeout)
.then(() => {
onSuccess();
})
.catch(() => {
if (!self.running) {
return;
}
self.retryLoadRemoteFont(typeface, timeout, onSuccess);
});
},
async openTerm(root, callbacks) {
const self = this;
return self
.loadRemoteFont(termTypeFace, termTypeFaceLoadTimeout)
.then(() => {
if (!self.running) {
return;
}
root.innerHTML = "";
self.term.init(root, callbacks);
})
.catch(() => {
if (!self.running) {
return;
}
root.innerHTML = "";
callbacks.warn(termTypeFaceLoadError, false);
self.term.setFont(termFallbackTypeFace);
self.term.init(root, callbacks);
self.retryLoadRemoteFont(
termTypeFace,
termTypeFaceLoadTimeout,
() => {
if (!self.running) {
return;
}
self.term.setFont(termTypeFace);
callbacks.warn(termTypeFaceLoadError, true);
}
);
});
},
triggerActive() {
this.active ? this.activate() : this.deactivate();
},
async init() {
let self = this;
await this.term.init(
await this.openTerm(
this.$el.getElementsByClassName("console-console")[0],
{
focus(e) {
@@ -430,15 +492,20 @@ export default {
document.removeEventListener("keyup", self.localKeypress);
document.removeEventListener("keydown", self.localKeypress);
},
warn(msg) {
self.$emit("warning", msg);
warn(msg, toDismiss) {
self.$emit("warning", {
text: msg,
toDismiss: toDismiss
});
},
info(msg) {
self.$emit("info", msg);
info(msg, toDismiss) {
self.$emit("info", {
text: msg,
toDismiss: toDismiss
});
}
}
);
this.triggerActive();
this.runRunner();
},

View File

@@ -40,7 +40,7 @@
<div class="screen-screen" style="position: relative">
<component
:is="getComponent(screenInfo.control.ui())"
:is="getComponent(screenInfo.ui)"
:active="screen === idx"
:control="screenInfo.control"
:change="screenInfo.indicator"