-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Smarter placeholders - Merged placeholders with real templates to avoid maintening duplicates - Moved style/js away from index.html and refactor - Svg size is now computed again from templates - Base metrics is now contained in special plugin "base", which can be disabled part by part if you just want to include a plugin instead - Reformatted a bit terminal template - Test now look templates directory
- Loading branch information
1 parent
997deed
commit 60d02a6
Showing
22 changed files
with
707 additions
and
950 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
;(async function() { | ||
//Init | ||
const url = new URLSearchParams(window.location.search) | ||
const {data:templates} = await axios.get("/templates.list") | ||
const {data:plugins} = await axios.get("/plugins.list") | ||
const {data:base} = await axios.get("/plugins.base.parts.list") | ||
//App | ||
return new Vue({ | ||
//Initialization | ||
el:"main", | ||
async mounted() { | ||
await this.load() | ||
}, | ||
//Data initialization | ||
data:{ | ||
user:url.get("user") || "", | ||
palette:url.get("palette") || "light", | ||
plugins:{ | ||
base, | ||
list:plugins, | ||
enabled:{base:Object.fromEntries(base.map(key => [key, true]))}, | ||
descriptions:{ | ||
pagespeed:"Website performances", | ||
languages:"Most used languages", | ||
followup:"Issues and pull requests", | ||
traffic:"Pages views", | ||
lines:"Lines of code changed", | ||
habits:"Coding habits", | ||
selfskip:"Skip metrics commits", | ||
"base.header":"Header", | ||
"base.activity":"Account activity", | ||
"base.community":"Community stats", | ||
"base.repositories":"Repositories metrics", | ||
"base.metadata":"Metadata", | ||
}, | ||
}, | ||
templates:{ | ||
list:templates, | ||
selected:url.get("template") || templates[0], | ||
loaded:{}, | ||
placeholder:"", | ||
descriptions:{ | ||
classic:"Classic template", | ||
terminal:"Terminal template", | ||
}, | ||
}, | ||
generated:{ | ||
pending:false, | ||
content:"", | ||
error:false, | ||
}, | ||
}, | ||
//Computed data | ||
computed:{ | ||
//User's repository | ||
repo() { | ||
return `https://github.com/${this.user}/${this.user}` | ||
}, | ||
//Endpoint to use for computed metrics | ||
url() { | ||
const plugins = Object.entries(this.plugins.enabled) | ||
.flatMap(([key, value]) => key === "base" ? Object.entries(value).map(([key, value]) => [`base.${key}`, value]) : [[key, value]]) | ||
.filter(([key, value]) => /^base[.]\w+$/.test(key) ? !value : value) | ||
.map(([key, value]) => `${key}=${+value}`) | ||
const params = [...(this.templates.selected !== templates[0] ? [`template=${this.templates.selected}`] : []), ...plugins].join("&") | ||
return `${window.location.protocol}//${window.location.host}/${this.user}${params.length ? `?${params}` : ""}` | ||
}, | ||
}, | ||
//Methods | ||
methods:{ | ||
//Load and render image | ||
async load() { | ||
//Load template | ||
const template = this.templates.selected | ||
if (!this.templates.loaded[template]) { | ||
const {data:{image, style}} = await axios.get(`/placeholder.svg?template=${template}`) | ||
this.templates.loaded[template] = {image, style} | ||
} | ||
const {image = "", style = {}} = this.templates.loaded[this.templates.selected] || {} | ||
if (!image) | ||
return this.templates.placeholder = "#" | ||
//Proxifier | ||
const proxify = (target) => typeof target === "object" ? new Proxy(target, { | ||
get(target, property) { | ||
//Primitive conversion | ||
if (property === Symbol.toPrimitive) | ||
return () => "▇" | ||
//Iterables | ||
if (property === Symbol.iterator) | ||
return Reflect.get(target, property) | ||
//Plugins should not be proxified by default as they can be toggled by user | ||
if (/^plugins$/.test(property)) | ||
return Reflect.get(target, property) | ||
//Consider no errors on plugins | ||
if (/^error/.test(property)) | ||
return undefined | ||
//Proxify recursively | ||
return proxify(property in target ? Reflect.get(target, property) : {}) | ||
} | ||
}) : target | ||
//Placeholder data | ||
const data = { | ||
style, | ||
s(_, letter) { return letter === "y" ? "ies" : "s" }, | ||
base:this.plugins.enabled.base, | ||
meta:{version:"0.0.0", author:"lowlighter", placeholder:true}, | ||
user:proxify({name:`▇▇▇▇`, websiteUrl:`▇▇▇▇▇▇▇▇▇▇▇▇`}), | ||
computed:proxify({ | ||
avatar:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==", | ||
registration:"▇ years ago", | ||
calendar:new Array(14).fill({color:"#ebedf0"}), | ||
licenses:{favorite:`▇▇▇▇`}, | ||
plugins:Object.fromEntries(Object.entries(this.plugins.enabled).filter(([key, enabled]) => (key !== "base")&&(enabled)).map(([key]) => { | ||
return [key, proxify({ | ||
pagespeed:{scores:["Performance", "Accessibility", "Best Practices", "SEO"].map(title => ({title, score:NaN}))}, | ||
followup:{issues:{count:0}, pr:{count:0}}, | ||
habits:{indents:{style:`▇▇▇`}}, | ||
languages:{favorites:new Array(7).fill(null).map((_, x) => ({x, name:`▇▇▇▇`, color:"#ebedf0", value:1/(x+1)}))}, | ||
}[key]||{})] | ||
})), | ||
token:{scopes:[]}, | ||
}), | ||
} | ||
//Render placeholder | ||
this.templates.placeholder = this.serialize(ejs.render(image, data)) | ||
this.generated.content = "" | ||
}, | ||
//Generate metrics and flush cache | ||
async generate() { | ||
//Avoid requests spamming | ||
if (this.generated.pending) | ||
return | ||
this.generated.pending = true | ||
//Compute metrics | ||
try { | ||
await axios.get(`/action.flush?&token=${(await axios.get(`/action.flush?user=${this.user}`)).data.token}`) | ||
this.generated.content = this.serialize((await axios.get(this.url)).data) | ||
} catch { | ||
this.generated.error = true | ||
} | ||
finally { | ||
this.generated.pending = false | ||
} | ||
}, | ||
//Serialize svg | ||
serialize(svg) { | ||
return `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svg)))}` | ||
}, | ||
}, | ||
}) | ||
})() |
Oops, something went wrong.