Skip to content

Commit

Permalink
Merge pull request #1 from nobkd/feat/loading-spinner
Browse files Browse the repository at this point in the history
feat: add loading spinner
  • Loading branch information
nobkd authored Dec 7, 2022
2 parents c56ed45 + 3547545 commit b376a6d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 11 deletions.
51 changes: 45 additions & 6 deletions src/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function getNonce(): string {
return text;
}

export type CookieObject = object & {headers?: {cookie: string}};
export type CookieObject = object & { headers?: { cookie: string } };

export async function getCookieObject(): Promise<CookieObject> {
const cookie: string | undefined = await vscode.commands.executeCommand('advent-of-vscode.loadCookie');
Expand All @@ -22,23 +22,62 @@ export async function getCookieObject(): Promise<CookieObject> {
return {};
}

export function getDefaultHtml(defaultData: any) {
const nonce = getNonce();
export function getDefaultHtml(defaultData: any, webview: vscode.Webview, context: vscode.ExtensionContext) {
const scriptNonce = getNonce();
const styleNonce = getNonce();

// TODO: insert loading spinner css
return `
<!DOCTYPE html>
<html lang="en" style="scrollbar-gutter: stable;">
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'nonce-${nonce}';"/>
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'nonce-${styleNonce}'; img-src https: ${webview.cspSource}; script-src 'nonce-${scriptNonce}';"/>
</head>
<body>
<div id="view">${defaultData}</div>
<script nonce="${nonce}">
<script nonce="${scriptNonce}">
window.addEventListener('message', event => document.getElementById('view').innerHTML = event.data);
</script>
<style nonce="${styleNonce}">
html {
scrollbar-gutter: stable;
width: calc(100vw - calc(100vw - 100%));
height: 100vh;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.spinner {
--size: clamp(15px, 10vmin, 50px);
position: absolute;
top: calc(50% - var(--size) / 2);
left: calc(50% - var(--size) / 2);
transform: translate(-50%, -50%);
height: var(--size);
width: var(--size);
background-image: url("${webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, 'res', 'icon.png'))}");
background-size: contain;
background-repeat: no-repeat;
animation: rotate 1.75s infinite; /* TODO: Maybe rotate all the time with 'alternate' (or so)? */
}
@keyframes rotate {
0% {
transform: rotate(0deg)
}
100% {
transform: rotate(360deg)
}
}
</style>
</body>
</html>
`;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function fetchDescription(year: number, day: number): Promise<strin
const dom = parse(data);
const dayDescriptions = dom.querySelectorAll('.day-desc');

// TODO: cache data
// TODO: cache data -> use global storage, how to check if part 2 now available?

/// loading all parts if logged in & part 1 completed
let html = '';
Expand Down
8 changes: 4 additions & 4 deletions src/views/descriptionView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class DescriptionView implements vscode.WebviewViewProvider {
private _panels: vscode.WebviewPanel[] = [];

private title: string = 'AoC Description';
private description: string = 'Please Select a Day';
private description: string = '<div class="center">Please Select a Day</div>';

constructor(private context: vscode.ExtensionContext) {
this.context.subscriptions.push(
Expand All @@ -25,10 +25,10 @@ export class DescriptionView implements vscode.WebviewViewProvider {
this._view.webview.options = { enableScripts: true };
this._view.description = this.title;

this._view.webview.html = getDefaultHtml(this.description);
this._view.webview.html = getDefaultHtml(this.description, webviewView.webview, this.context);
}

async descriptionPanel(): Promise<vscode.WebviewPanel> {
async descriptionPanel(): Promise<vscode.WebviewPanel> { // TODO: use workspaceStorage to reopen panels after reopening vscode
const panel: vscode.WebviewPanel = vscode.window.createWebviewPanel(`descriptionPanel-${getNonce()}`, // TODO: get UNIQUE nonce
this.title,
vscode.ViewColumn.Active,
Expand All @@ -53,7 +53,7 @@ export class DescriptionView implements vscode.WebviewViewProvider {
// TODO: get data from aoc / cache

this.title = `AoC ${year} Day ${day}`;
this.description = 'Please wait...'; // TODO: replace with animation (maybe AoVSC icon rotating)
this.description = '<div class="spinner"></div>';

this._view!.description = this.title;
this._view?.webview.postMessage(this.description);
Expand Down

0 comments on commit b376a6d

Please sign in to comment.