import * as vscode from "vscode" ; import { accessTokenKey , apiBaseUrl , refreshTokenKey } from "./constants" ; import { FlairProvider } from "./FlairProvider" ; import { getNonce } from "./getNonce" ; import { Util } from "./util" ; import jwt from "jsonwebtoken" ; export class ViewStoryPanel { /**
     * Track the currently panel. Only allow a single panel to exist at a time.
     */ public static currentPanel : ViewStoryPanel | undefined ; public static readonly viewType = "viewStory" ; private readonly _panel : vscode . WebviewPanel ; private readonly _extensionUri : vscode . Uri ; private _story : any ; private _disposables : vscode . Disposable [ ] = [ ] ; public static createOrShow ( extensionUri , story ) { const column = vscode . window . activeTextEditor ? vscode . window . activeTextEditor . viewColumn : undefined ; if ( ViewStoryPanel . currentPanel ) { ViewStoryPanel . currentPanel . _panel . reveal ( column ) ; ViewStoryPanel . currentPanel . _story = story ; ViewStoryPanel . currentPanel . _update ( ) ; return ; } const panel = vscode . window . createWebviewPanel ( ViewStoryPanel . viewType , "View Story" , column || vscode . ViewColumn . One , { enableScripts : true , localResourceRoots : [ vscode . Uri . joinPath ( extensionUri , "media" ) , vscode . Uri . joinPath ( extensionUri , "out/compiled" ) , ] , } ) ; ViewStoryPanel . currentPanel = new ViewStoryPanel ( panel , extensionUri , story ) ; } public static revive ( panel , extensionUri , story ) { ViewStoryPanel . currentPanel = new ViewStoryPanel ( panel , extensionUri , story ) ; } private constructor ( panel , extensionUri , story ) { this . _panel = panel ; this . _extensionUri = extensionUri ; this . _story = story ; this . _update ( ) ; this . _panel . onDidDispose ( ( ) => this . dispose ( ) , null , this . _disposables ) ; } public dispose ( ) { ViewStoryPanel . currentPanel = undefined ; this . _panel . dispose ( ) ; while ( this . _disposables . length ) { const x = this . _disposables . pop ( ) ; if ( x ) { x . dispose ( ) ; } } } private async _update ( ) { const webview = this . _panel . webview ; this . _panel . webview . html = this . _getHtmlForWebview ( webview ) ; webview . onDidReceiveMessage ( async ( data ) => { switch ( data . type ) { case "close" : { vscode . commands . executeCommand ( "workbench.action.closeActiveEditor" ) ; break ; } case "onInfo" : { if ( ! data . value ) { return ; } vscode . window . showInformationMessage ( data . value ) ; break ; } case "onError" : { if ( ! data . value ) { return ; } vscode . window . showErrorMessage ( data . value ) ; break ; } case "tokens" : { await Util . context . globalState . update ( accessTokenKey , data . accessToken ) ; await Util . context . globalState . update ( refreshTokenKey , data . refreshToken ) ; break ; } } } ) ; } private _getHtmlForWebview ( webview ) { const scriptUri = webview . asWebviewUri ( vscode . Uri . joinPath ( this . _extensionUri , "out" , "compiled/view-story.js" ) ) ; const styleResetPath = vscode . Uri . joinPath ( this . _extensionUri , "media" , "reset.css" ) ; const stylesPathMainPath = vscode . Uri . joinPath ( this . _extensionUri , "media" , "vscode.css" ) ; const stylesResetUri = webview . asWebviewUri ( styleResetPath ) ; const stylesMainUri = webview . asWebviewUri ( stylesPathMainPath ) ; const cssUri = webview . asWebviewUri ( vscode . Uri . joinPath ( this . _extensionUri , "out" , "compiled/view-story.css" ) ) ; const nonce = getNonce ( ) ; const story = this . _story ; this . _panel . title = story . creatorUsername ; if ( story . flair in FlairProvider . flairUriMap ) { const both = FlairProvider . flairUriMap [ story . flair ] ; this . _panel . iconPath = { light : both , dark : both , } ; } else { this . _panel . iconPath = undefined ; } let currentUserId = "" ; try { const payload = jwt . decode ( Util . getAccessToken ( ) ) ; currentUserId = payload . userId ; } catch { } return `<!DOCTYPE html>
			<html lang="en">
			<head>
				<meta charset="UTF-8">
				<!--
					Use a content security policy to only allow loading images from https or from our extension directory,
					and only allow scripts that have a specific nonce.
        -->
        <meta http-equiv="Content-Security-Policy" content="default-src ${ apiBaseUrl }; img-src https: data:; style-src ${ webview . cspSource }; script-src 'nonce-${ nonce }';">
				<meta name="viewport" content="width=device-width, initial-scale=1.0">
				<link href="${ stylesResetUri }" rel="stylesheet">
				<link href="${ stylesMainUri }" rel="stylesheet">
        <link href="${ cssUri }" rel="stylesheet">
        <script nonce="${ nonce }">
            const currentUserId = "${ currentUserId }";
            const story = JSON.parse('${ JSON . stringify ( this . _story ) }');
            let accessToken = "${ Util . getAccessToken ( ) }";
            let refreshToken = "${ Util . getRefreshToken ( ) }";
            const apiBaseUrl = "${ apiBaseUrl }";
            const tsvscode = acquireVsCodeApi();
            ${ FlairProvider . getJavascriptMapString ( ) }
        </script>
			</head>
      <body>
			</body>
				<script nonce="${ nonce }" src="${ scriptUri }"></script>
			</html>` ; } }