Skip to content

Instantly share code, notes, and snippets.

@frankli0324
Created May 2, 2022 16:54
Show Gist options
  • Save frankli0324/a95dbac31766266788d001757c7ed55f to your computer and use it in GitHub Desktop.
Save frankli0324/a95dbac31766266788d001757c7ed55f to your computer and use it in GitHub Desktop.
<template>
<div class="terminal">
<div>$ Rankings</div>
{{ border }}
<br />
{{ header.replaceAll(" ", "&nbsp;") }}
<br />
{{ border }}
<br />
<template v-for="(line, idx) in raw_data.items" :key="idx">
{{ renderLine(line).replaceAll(" ", "&nbsp;") }}
<br />
{{ border }}
<br />
</template>
</div>
</template>
<script>
import 'hack-font/build/web/hack.css'
export default {
components: {},
props: {
initial: Object,
key_idx: Number,
},
mounted() {
this.raw_data = this.initial;
for (let i in this.raw_data.items) {
this.order[this.raw_data.items[i][this.key_idx]] = i;
}
},
data() {
return {
raw_data: { head: [], items: [] },
lines: [],
order: [], // k(line number) -> v(line key)
col_widths: [],
line_locks: [],
}
},
computed: {
header: function () {
for (let i in this.col_widths) {
this.col_widths[i];
}
return this.renderLine(this.raw_data.head);
},
border: function () {
let border = '+';
for (let k = 0; k < this.col_widths.length; k++) {
border += '-'.repeat(this.col_widths[k] + 2) + '+';
}
return border;
}
},
methods: {
renderLine(data) {
let line = '|';
for (let v in data) {
let res = (this.col_widths[v] || 0) + 2 - String(data[v]).length;
if (res < 2) {
this.col_widths[v] = String(data[v]).length;
res = this.col_widths[v] + 2 - String(data[v]).length;
}
let half = Math.floor(res / 2);
line += `${' '.repeat(half)}${data[v]}${' '.repeat(res - half)}|`;
}
return line;
},
updateLine(data) {
let idx = this.order[data[this.key_idx]];
if (data.length !== this.raw_data.items[idx].length) {
return false;
}
let app = this;
async function updateEffect(col, i) {
let oldstr = String(app.raw_data.items[idx][col]);
let newstr = String(data[col]);
if (i >= newstr.length) {
app.raw_data.items[idx][col] = newstr;
app.col_widths[col] = Math.max(
app.raw_data.head[col].length,
...app.raw_data.items.map((item) => String(item[col]).length)
);
return;
}
if (oldstr[i] === newstr[i]) {
updateEffect(col, i + 1);
return;
}
app.raw_data.items[idx][col] = oldstr.slice(0, i) + newstr[i] + oldstr.slice(i + 1);
setTimeout(() => {
updateEffect(col, i + 1);
}, 50);
}
async function performUpdate() {
app.line_locks[idx] = true;
let old_data = app.raw_data.items[idx];
/* eslint-disable */
async function updateSingle(i) {
if (i >= data.length) return;
if (old_data[i] === data[i]) {
updateSingle(i + 1);
return;
}
if (data[i].length > app.col_widths[i]) {
app.col_widths[i] = data[i].length;
}
await updateEffect(i, 0);
setTimeout(() => {
updateSingle(i + 1);
}, 50);
}
await updateSingle(0);
app.line_locks[idx] = false;
}
function check() {
if (app.line_locks[idx]) {
setTimeout(() => { check(); }, 50);
} else {
performUpdate();
}
}
check();
},
},
}
</script>
<style scoped>
.terminal {
font-family: Hack, monospace;
font-weight: bold;
box-sizing: border-box;
width: 100%;
height: 100%;
background: black;
color: white;
padding: 10px 30px;
font-size: 15px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment