From f91626137d6ae1953f8e70bb7eee2f9c46313e57 Mon Sep 17 00:00:00 2001 From: DATBOI Date: Sat, 25 Apr 2020 19:01:53 -0500 Subject: [PATCH 1/6] Everything is broke and I am having a hard time finding out what is going on --- src/ENV.ts | 22 ++++++++++ src/RESTClient.ts | 5 ++- src/StickerService.ts | 86 +++++-------------------------------- src/StickerUpdateService.ts | 80 +++++++++++++++++++++++++++++----- src/ThemeManager.ts | 5 +-- 5 files changed, 109 insertions(+), 89 deletions(-) diff --git a/src/ENV.ts b/src/ENV.ts index 0901041..cf4263a 100644 --- a/src/ENV.ts +++ b/src/ENV.ts @@ -1,4 +1,26 @@ + +import path from 'path'; +import fs from "fs"; + export const ASSETS_URL = `https://doki.assets.unthrottled.io`; export const VSCODE_ASSETS_URL = `${ASSETS_URL}/stickers/vscode`; export const BACKGROUND_ASSETS_URL = `${ASSETS_URL}/backgrounds`; export const SCREENSHOT_ASSETS_URL = `${ASSETS_URL}/screenshots`; + + +const main = require.main || { filename: 'yeet' }; +export const workbenchDirectory = path.join(path.dirname(main.filename), 'vs', 'workbench'); + +const CODE_SERVER_FILE = 'web.api'; +const getFileName = () => { + return fs.existsSync(path.join(workbenchDirectory, `workbench.desktop.main.css`)) ? + 'desktop.main' : CODE_SERVER_FILE; +}; + +const fileName = getFileName(); + +export const editorCss = path.join(workbenchDirectory, `workbench.${fileName}.css`); +export const editorCssCopy = path.join(workbenchDirectory, `workbench.${fileName}.css.copy`); + + +export const isCodeServer = () => fileName === CODE_SERVER_FILE; \ No newline at end of file diff --git a/src/RESTClient.ts b/src/RESTClient.ts index 52e6ae1..53418af 100644 --- a/src/RESTClient.ts +++ b/src/RESTClient.ts @@ -3,7 +3,10 @@ import { Transform as Stream } from 'stream'; export const performGet = (url: string): Promise => { return new Promise((resolve, reject) => { - https.get(url, (res) => { + https.get({ + href: url, + timeout: 10000, + }, (res) => { const inputStream = new Stream(); res.on('data', (d) => { inputStream.push(d); diff --git a/src/StickerService.ts b/src/StickerService.ts index c8693a6..3e25282 100644 --- a/src/StickerService.ts +++ b/src/StickerService.ts @@ -1,32 +1,13 @@ import * as vscode from "vscode"; import { DokiTheme } from "./DokiTheme"; -import path from 'path'; import fs from "fs"; -import { resolveLocalStickerPath, isStickerNotCurrent, StickerUpdateStatus, stickerPathToUrl, cleanPathToUrl } from "./StickerUpdateService"; -import { performGet } from "./RESTClient"; -import { ASSETS_URL, BACKGROUND_ASSETS_URL, VSCODE_ASSETS_URL } from "./ENV"; +import { ASSETS_URL, editorCss, editorCssCopy } from "./ENV"; +import { getLatestStickerAndBackground } from "./StickerUpdateService"; export enum InstallStatus { INSTALLED, NOT_INSTALLED, FAILURE } -const main = require.main || { filename: 'yeet' }; -export const workbenchDirectory = path.join(path.dirname(main.filename), 'vs', 'workbench'); - -const CODE_SERVER_FILE = 'web.api'; -const getFileName = () => { - return fs.existsSync(path.join(workbenchDirectory, `workbench.desktop.main.css`)) ? - 'desktop.main' : CODE_SERVER_FILE; -}; - -const fileName = getFileName(); - -const editorCss = path.join(workbenchDirectory, `workbench.${fileName}.css`); -const editorCssCopy = path.join(workbenchDirectory, `workbench.${fileName}.css.copy`); - - -const isCodeServer = () => fileName === CODE_SERVER_FILE; - // Was VS Code upgraded when stickers where installed? function isCssPrestine() { const currentCss = fs.readFileSync(editorCss, 'utf-8'); @@ -46,20 +27,20 @@ function getVsCodeCss() { function buildStickerCss({ stickerDataURL: stickerUrl, - backgroundImageURL: backgroundImage + backgroundImageURL: wallpaperUrl }: DokiStickers): string { - const style = 'content:\'\';pointer-events:none;position:absolute;z-index:99999;width:100%;height:100%;background-position:100% 100%;background-repeat:no-repeat;opacity:1;'; + const style = 'content:\'\';pointer-events:none;position:absolute;z-index:9001;width:100%;height:100%;background-position:100% 100%;background-repeat:no-repeat;opacity:1;'; return ` /* Stickers */ .split-view-view .editor-container .editor-instance>.monaco-editor .overflow-guard>.monaco-scrollable-element::after{background-image: url('${stickerUrl}');${style}} /* Background Image */ .monaco-workbench .part.editor > .content { - background-image: url('${BACKGROUND_ASSETS_URL}/${backgroundImage}') !important; + background-image: url('${wallpaperUrl}') !important; background-position: center; background-size: cover; content:''; - z-index:99999; + z-index:9001; width:100%; height:100%; background-repeat:no-repeat; @@ -72,6 +53,7 @@ function buildStyles(dokiStickers: DokiStickers): string { return `${getVsCodeCss()}${buildStickerCss(dokiStickers)}`; } + function installEditorStyles(styles: string) { fs.writeFileSync(editorCss, styles, 'utf-8'); } @@ -90,63 +72,17 @@ export interface DokiStickers { backgroundImageURL: string; } -const downloadSticker = async (stickerPath: string, localDestination: string) => { - const parentDirectory = path.dirname(localDestination); - if (!fs.existsSync(parentDirectory)) { - fs.mkdirSync(parentDirectory, { recursive: true }); - } - - const stickerUrl = `${VSCODE_ASSETS_URL}${stickerPath}`; - console.log(`Downloading image: ${stickerUrl}`); - const stickerInputStream = await performGet(stickerUrl); - console.log('Image Downloaded!'); - fs.writeFileSync(localDestination, stickerInputStream.read()); -}; - -const readFileToDataURL = (localStickerPath: string): string => { - if(isCodeServer()) { - const base64ImageString = fs.readFileSync(localStickerPath, {encoding: 'base64'}); - return `data:image/png;base64,${base64ImageString}`; - } - - return `file://${cleanPathToUrl(localStickerPath)}`; -}; - -export async function getLatestStickerAndBackground( - dokiTheme: DokiTheme, - context: vscode.ExtensionContext, - stickerStatus: StickerUpdateStatus -): Promise { - const localStickerPath = resolveLocalStickerPath( - dokiTheme, context - ); - if (stickerStatus === StickerUpdateStatus.STALE || - !fs.existsSync(localStickerPath) || - await isStickerNotCurrent(dokiTheme, localStickerPath)) { - await downloadSticker(stickerPathToUrl(dokiTheme), localStickerPath); - } - - const stickerDataURL = readFileToDataURL(localStickerPath); - - return { - stickerDataURL, - backgroundImageURL: dokiTheme.sticker.name - }; -} - -export async function installSticker( +export async function installStickersAndWallPaper( dokiTheme: DokiTheme, context: vscode.ExtensionContext, - stickerStatus: StickerUpdateStatus = StickerUpdateStatus.NOT_CHECKED ): Promise { if (canWrite()) { try { - const stickersAndBackground = await getLatestStickerAndBackground( + const stickersAndWallpaper = await getLatestStickerAndBackground( dokiTheme, - context, - stickerStatus + context ); - const stickerStyles = buildStyles(stickersAndBackground); + const stickerStyles = buildStyles(stickersAndWallpaper); installEditorStyles(stickerStyles); return true; } catch (e) { diff --git a/src/StickerUpdateService.ts b/src/StickerUpdateService.ts index 121cc1c..c4c9463 100644 --- a/src/StickerUpdateService.ts +++ b/src/StickerUpdateService.ts @@ -1,16 +1,16 @@ import * as vscode from 'vscode'; import { getCurrentTheme } from './ThemeManager'; import { performGet } from './RESTClient'; -import { installSticker } from './StickerService'; import { DokiTheme } from './DokiTheme'; import path from 'path'; import fs from 'fs'; import crypto from 'crypto'; -import { VSCODE_ASSETS_URL } from './ENV'; +import { VSCODE_ASSETS_URL, isCodeServer } from './ENV'; +import { DokiStickers } from './StickerService'; -const fetchRemoteChecksum = async (currentTheme: DokiTheme) => { - const checksumUrl = `${VSCODE_ASSETS_URL}${stickerPathToUrl(currentTheme)}.checksum.txt`; - console.log(`Fetching checksum: ${checksumUrl}`); +const fetchRemoteChecksum = async (remoteAssetUrl: string) => { + const checksumUrl = `${remoteAssetUrl}.checksum.txt`; + console.log(`Fetching resource checksum: ${checksumUrl}`); const checkSumInputStream = await performGet(checksumUrl); return checkSumInputStream.setEncoding('utf8').read(); }; @@ -23,7 +23,31 @@ export const resolveLocalStickerPath = ( return path.join(context.globalStoragePath, 'stickers', safeStickerPath); }; -export function cleanPathToUrl(stickerPath: string) { +export async function getLatestStickerAndBackground( + dokiTheme: DokiTheme, + context: vscode.ExtensionContext, +): Promise { + const localStickerPath = resolveLocalStickerPath( + dokiTheme, context + ); + const stickerDataURL = createStickerUrl(localStickerPath); + return { + stickerDataURL, + backgroundImageURL: dokiTheme.sticker.name + }; +} + +const createStickerUrl = (localStickerPath: string): string => { + // todo: just use remote urls for code server + if (isCodeServer()) { + const base64ImageString = fs.readFileSync(localStickerPath, { encoding: 'base64' }); + return `data:image/png;base64,${base64ImageString}`; + } + + return `file://${cleanPathToUrl(localStickerPath)}`; +}; + +function cleanPathToUrl(stickerPath: string) { return stickerPath.replace(/\\/g, '/'); } @@ -49,11 +73,11 @@ const fetchLocalChecksum = async (localSticker: string) => { }; export const isStickerNotCurrent = async ( - dokiTheme: DokiTheme, + remoteAssetUrl: string, localStickerPath: string ): Promise => { try { - const remoteChecksum = await fetchRemoteChecksum(dokiTheme); + const remoteChecksum = await fetchRemoteChecksum(remoteAssetUrl); const localChecksum = await fetchLocalChecksum(localStickerPath); return remoteChecksum !== localChecksum; } catch (e) { @@ -67,8 +91,44 @@ export enum StickerUpdateStatus { export const attemptToUpdateSticker = async (context: vscode.ExtensionContext) => { const currentTheme = getCurrentTheme(); + // todo: wallpaper const localStickerPath = resolveLocalStickerPath(currentTheme, context); - if (await isStickerNotCurrent(currentTheme, localStickerPath)) { - await installSticker(currentTheme, context, StickerUpdateStatus.STALE); + const remoteStickerUrl = `${VSCODE_ASSETS_URL}${stickerPathToUrl(currentTheme)}`; + if (await isStickerNotCurrent(remoteStickerUrl, localStickerPath)) { + await installAsset( + remoteStickerUrl, + localStickerPath + ); } }; + +const downloadRemoteAsset = async ( + remoteAssetUrl: string, + localDestination: string +) => { + const parentDirectory = path.dirname(localDestination); + if (!fs.existsSync(parentDirectory)) { + fs.mkdirSync(parentDirectory, { recursive: true }); + } + console.log(`Downloading remote asset: ${remoteAssetUrl}`); + const stickerInputStream = await performGet(remoteAssetUrl); + console.log('Image Downloaded!'); + fs.writeFileSync(localDestination, stickerInputStream.read()); +}; + +async function installAsset( + remoteAssetUrl: string, + localAssetPath: string, +): Promise { + try { + await downloadRemoteAsset( + remoteAssetUrl, + localAssetPath, + ); + return true; + } catch (e) { + console.error(`Unable to install asset ${remoteAssetUrl}!`, e); + } + + return false; +} \ No newline at end of file diff --git a/src/ThemeManager.ts b/src/ThemeManager.ts index 92fc64e..c14df25 100644 --- a/src/ThemeManager.ts +++ b/src/ThemeManager.ts @@ -1,6 +1,6 @@ import * as vscode from "vscode"; import {DokiTheme} from "./DokiTheme"; -import {InstallStatus, installSticker, removeStickers} from "./StickerService"; +import {InstallStatus, installAsset, removeStickers, installStickersAndWallPaper} from "./StickerService"; import {VSCodeGlobals} from "./VSCodeGlobals"; import {StatusBarComponent} from "./StatusBar"; import {showStickerInstallationSupportWindow, showStickerRemovalSupportWindow} from "./SupportService"; @@ -8,7 +8,6 @@ import DokiThemeDefinitions from "./DokiThemeDefinitions"; export const ACTIVE_THEME = 'doki.theme.active'; - const FIRST_TIME_STICKER_INSTALL = 'doki.sticker.first.install'; function isFirstTimeInstalling(context: vscode.ExtensionContext) { return !context.globalState.get(FIRST_TIME_STICKER_INSTALL); @@ -41,7 +40,7 @@ async function performStickerInstall( dokiTheme: DokiTheme, context: vscode.ExtensionContext ): Promise { - const installResult = await installSticker(dokiTheme, context); + const installResult = await installStickersAndWallPaper(dokiTheme, context); return installResult ? InstallStatus.INSTALLED : InstallStatus.FAILURE; } From 2abbc568e7ca4cfba2c704717bc1f8725769dba2 Mon Sep 17 00:00:00 2001 From: DATBOI Date: Sat, 25 Apr 2020 19:09:38 -0500 Subject: [PATCH 2/6] Okay so all the update junk is in the update service --- src/StickerService.ts | 1 - src/StickerUpdateService.ts | 117 +++++++++++++++++------------------- src/ThemeManager.ts | 3 +- src/extension.ts | 2 +- 4 files changed, 57 insertions(+), 66 deletions(-) diff --git a/src/StickerService.ts b/src/StickerService.ts index 3e25282..5eabb9d 100644 --- a/src/StickerService.ts +++ b/src/StickerService.ts @@ -51,7 +51,6 @@ function buildStickerCss({ function buildStyles(dokiStickers: DokiStickers): string { return `${getVsCodeCss()}${buildStickerCss(dokiStickers)}`; - } function installEditorStyles(styles: string) { diff --git a/src/StickerUpdateService.ts b/src/StickerUpdateService.ts index c4c9463..10c629e 100644 --- a/src/StickerUpdateService.ts +++ b/src/StickerUpdateService.ts @@ -1,46 +1,60 @@ -import * as vscode from 'vscode'; -import { getCurrentTheme } from './ThemeManager'; -import { performGet } from './RESTClient'; -import { DokiTheme } from './DokiTheme'; -import path from 'path'; -import fs from 'fs'; -import crypto from 'crypto'; -import { VSCODE_ASSETS_URL, isCodeServer } from './ENV'; -import { DokiStickers } from './StickerService'; +import * as vscode from "vscode"; +import { getCurrentTheme } from "./ThemeManager"; +import { performGet } from "./RESTClient"; +import { DokiTheme } from "./DokiTheme"; +import path from "path"; +import fs from "fs"; +import crypto from "crypto"; +import { VSCODE_ASSETS_URL, isCodeServer } from "./ENV"; +import { DokiStickers } from "./StickerService"; -const fetchRemoteChecksum = async (remoteAssetUrl: string) => { - const checksumUrl = `${remoteAssetUrl}.checksum.txt`; - console.log(`Fetching resource checksum: ${checksumUrl}`); - const checkSumInputStream = await performGet(checksumUrl); - return checkSumInputStream.setEncoding('utf8').read(); -}; - -export const resolveLocalStickerPath = ( - currentTheme: DokiTheme, - context: vscode.ExtensionContext, -): string => { - const safeStickerPath = stickerPathToUrl(currentTheme); - return path.join(context.globalStoragePath, 'stickers', safeStickerPath); +export const attemptToUpdateSticker = async ( + context: vscode.ExtensionContext +) => { + const currentTheme = getCurrentTheme(); + // todo: wallpaper + const localStickerPath = resolveLocalStickerPath(currentTheme, context); + const remoteStickerUrl = `${VSCODE_ASSETS_URL}${stickerPathToUrl( + currentTheme + )}`; + if (await isStickerNotCurrent(remoteStickerUrl, localStickerPath)) { + await installAsset(remoteStickerUrl, localStickerPath); + } }; export async function getLatestStickerAndBackground( dokiTheme: DokiTheme, - context: vscode.ExtensionContext, + context: vscode.ExtensionContext ): Promise { - const localStickerPath = resolveLocalStickerPath( - dokiTheme, context - ); + const localStickerPath = resolveLocalStickerPath(dokiTheme, context); const stickerDataURL = createStickerUrl(localStickerPath); return { stickerDataURL, - backgroundImageURL: dokiTheme.sticker.name + backgroundImageURL: dokiTheme.sticker.name, }; } +const fetchRemoteChecksum = async (remoteAssetUrl: string) => { + const checksumUrl = `${remoteAssetUrl}.checksum.txt`; + console.log(`Fetching resource checksum: ${checksumUrl}`); + const checkSumInputStream = await performGet(checksumUrl); + return checkSumInputStream.setEncoding("utf8").read(); +}; + +const resolveLocalStickerPath = ( + currentTheme: DokiTheme, + context: vscode.ExtensionContext +): string => { + const safeStickerPath = stickerPathToUrl(currentTheme); + return path.join(context.globalStoragePath, "stickers", safeStickerPath); +}; + const createStickerUrl = (localStickerPath: string): string => { // todo: just use remote urls for code server if (isCodeServer()) { - const base64ImageString = fs.readFileSync(localStickerPath, { encoding: 'base64' }); + const base64ImageString = fs.readFileSync(localStickerPath, { + encoding: "base64", + }); return `data:image/png;base64,${base64ImageString}`; } @@ -48,18 +62,16 @@ const createStickerUrl = (localStickerPath: string): string => { }; function cleanPathToUrl(stickerPath: string) { - return stickerPath.replace(/\\/g, '/'); + return stickerPath.replace(/\\/g, "/"); } -export function stickerPathToUrl(currentTheme: DokiTheme) { +function stickerPathToUrl(currentTheme: DokiTheme) { const stickerPath = currentTheme.sticker.path; return cleanPathToUrl(stickerPath); } -export function createChecksum(data: Buffer | string): string { - return crypto.createHash('md5') - .update(data) - .digest('hex'); +function createChecksum(data: Buffer | string): string { + return crypto.createHash("md5").update(data).digest("hex"); } const calculateFileChecksum = (filePath: string): string => { @@ -68,11 +80,12 @@ const calculateFileChecksum = (filePath: string): string => { }; const fetchLocalChecksum = async (localSticker: string) => { - return fs.existsSync(localSticker) ? - calculateFileChecksum(localSticker) : 'File not downloaded, bruv.'; + return fs.existsSync(localSticker) + ? calculateFileChecksum(localSticker) + : "File not downloaded, bruv."; }; -export const isStickerNotCurrent = async ( +const isStickerNotCurrent = async ( remoteAssetUrl: string, localStickerPath: string ): Promise => { @@ -81,26 +94,10 @@ export const isStickerNotCurrent = async ( const localChecksum = await fetchLocalChecksum(localStickerPath); return remoteChecksum !== localChecksum; } catch (e) { - console.error('Unable to check for updates', e); + console.error("Unable to check for updates", e); return false; } }; -export enum StickerUpdateStatus { - CURRENT, STALE, NOT_CHECKED, -} - -export const attemptToUpdateSticker = async (context: vscode.ExtensionContext) => { - const currentTheme = getCurrentTheme(); - // todo: wallpaper - const localStickerPath = resolveLocalStickerPath(currentTheme, context); - const remoteStickerUrl = `${VSCODE_ASSETS_URL}${stickerPathToUrl(currentTheme)}`; - if (await isStickerNotCurrent(remoteStickerUrl, localStickerPath)) { - await installAsset( - remoteStickerUrl, - localStickerPath - ); - } -}; const downloadRemoteAsset = async ( remoteAssetUrl: string, @@ -112,23 +109,19 @@ const downloadRemoteAsset = async ( } console.log(`Downloading remote asset: ${remoteAssetUrl}`); const stickerInputStream = await performGet(remoteAssetUrl); - console.log('Image Downloaded!'); + console.log("Image Downloaded!"); fs.writeFileSync(localDestination, stickerInputStream.read()); }; async function installAsset( remoteAssetUrl: string, - localAssetPath: string, + localAssetPath: string ): Promise { try { - await downloadRemoteAsset( - remoteAssetUrl, - localAssetPath, - ); + await downloadRemoteAsset(remoteAssetUrl, localAssetPath); return true; } catch (e) { console.error(`Unable to install asset ${remoteAssetUrl}!`, e); } - return false; -} \ No newline at end of file +} diff --git a/src/ThemeManager.ts b/src/ThemeManager.ts index c14df25..5569e9c 100644 --- a/src/ThemeManager.ts +++ b/src/ThemeManager.ts @@ -1,6 +1,6 @@ import * as vscode from "vscode"; import {DokiTheme} from "./DokiTheme"; -import {InstallStatus, installAsset, removeStickers, installStickersAndWallPaper} from "./StickerService"; +import {InstallStatus, removeStickers, installStickersAndWallPaper} from "./StickerService"; import {VSCodeGlobals} from "./VSCodeGlobals"; import {StatusBarComponent} from "./StatusBar"; import {showStickerInstallationSupportWindow, showStickerRemovalSupportWindow} from "./SupportService"; @@ -61,7 +61,6 @@ export function activateTheme( }); } - // :( export function uninstallImages( context: vscode.ExtensionContext diff --git a/src/extension.ts b/src/extension.ts index 7bc32e4..bfc254b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { activateTheme, ACTIVE_THEME, uninstallImages } from "./ThemeManager"; +import { activateTheme, uninstallImages } from "./ThemeManager"; import { DokiTheme } from "./DokiTheme"; import DokiThemeDefinitions from './DokiThemeDefinitions'; import { StatusBarComponent } from './StatusBar'; From ddb0f612ec87b369d3f7c04cb3d678aaa8e8be18 Mon Sep 17 00:00:00 2001 From: DATBOI Date: Sat, 25 Apr 2020 19:24:35 -0500 Subject: [PATCH 3/6] This looks right? --- src/StickerService.ts | 29 ++++++----- src/StickerUpdateService.ts | 68 +++++++++++++++---------- src/extension.ts | 98 +++++++++++++++++-------------------- 3 files changed, 105 insertions(+), 90 deletions(-) diff --git a/src/StickerService.ts b/src/StickerService.ts index 5eabb9d..3999fb7 100644 --- a/src/StickerService.ts +++ b/src/StickerService.ts @@ -2,15 +2,17 @@ import * as vscode from "vscode"; import { DokiTheme } from "./DokiTheme"; import fs from "fs"; import { ASSETS_URL, editorCss, editorCssCopy } from "./ENV"; -import { getLatestStickerAndBackground } from "./StickerUpdateService"; +import { attemptToUpdateSticker } from "./StickerUpdateService"; export enum InstallStatus { - INSTALLED, NOT_INSTALLED, FAILURE + INSTALLED, + NOT_INSTALLED, + FAILURE, } // Was VS Code upgraded when stickers where installed? function isCssPrestine() { - const currentCss = fs.readFileSync(editorCss, 'utf-8'); + const currentCss = fs.readFileSync(editorCss, "utf-8"); return currentCss.indexOf(ASSETS_URL) < 0; } @@ -22,14 +24,15 @@ function ensureRightCssCopy() { function getVsCodeCss() { ensureRightCssCopy(); - return fs.readFileSync(editorCssCopy, 'utf-8'); + return fs.readFileSync(editorCssCopy, "utf-8"); } function buildStickerCss({ stickerDataURL: stickerUrl, - backgroundImageURL: wallpaperUrl + backgroundImageURL: wallpaperUrl, }: DokiStickers): string { - const style = 'content:\'\';pointer-events:none;position:absolute;z-index:9001;width:100%;height:100%;background-position:100% 100%;background-repeat:no-repeat;opacity:1;'; + const style = + "content:'';pointer-events:none;position:absolute;z-index:9001;width:100%;height:100%;background-position:100% 100%;background-repeat:no-repeat;opacity:1;"; return ` /* Stickers */ .split-view-view .editor-container .editor-instance>.monaco-editor .overflow-guard>.monaco-scrollable-element::after{background-image: url('${stickerUrl}');${style}} @@ -54,7 +57,7 @@ function buildStyles(dokiStickers: DokiStickers): string { } function installEditorStyles(styles: string) { - fs.writeFileSync(editorCss, styles, 'utf-8'); + fs.writeFileSync(editorCss, styles, "utf-8"); } function canWrite(): boolean { @@ -73,19 +76,19 @@ export interface DokiStickers { export async function installStickersAndWallPaper( dokiTheme: DokiTheme, - context: vscode.ExtensionContext, + context: vscode.ExtensionContext ): Promise { if (canWrite()) { try { - const stickersAndWallpaper = await getLatestStickerAndBackground( - dokiTheme, - context + const stickersAndWallpaper = await attemptToUpdateSticker( + context, + dokiTheme ); const stickerStyles = buildStyles(stickersAndWallpaper); installEditorStyles(stickerStyles); return true; } catch (e) { - console.error('Unable to install sticker!', e); + console.error("Unable to install sticker!", e); } } @@ -105,4 +108,4 @@ export function removeStickers(): InstallStatus { } return InstallStatus.FAILURE; -} \ No newline at end of file +} diff --git a/src/StickerUpdateService.ts b/src/StickerUpdateService.ts index 10c629e..d098831 100644 --- a/src/StickerUpdateService.ts +++ b/src/StickerUpdateService.ts @@ -9,29 +9,42 @@ import { VSCODE_ASSETS_URL, isCodeServer } from "./ENV"; import { DokiStickers } from "./StickerService"; export const attemptToUpdateSticker = async ( - context: vscode.ExtensionContext -) => { - const currentTheme = getCurrentTheme(); - // todo: wallpaper - const localStickerPath = resolveLocalStickerPath(currentTheme, context); + context: vscode.ExtensionContext, + currentTheme: DokiTheme, +): Promise => { const remoteStickerUrl = `${VSCODE_ASSETS_URL}${stickerPathToUrl( currentTheme )}`; - if (await isStickerNotCurrent(remoteStickerUrl, localStickerPath)) { - await installAsset(remoteStickerUrl, localStickerPath); + const remoteWallpaperUrl = `${VSCODE_ASSETS_URL}${wallpaperPathToUrl( + currentTheme + )}`; + if (isCodeServer()) { + return { + stickerDataURL: remoteStickerUrl, + backgroundImageURL: remoteWallpaperUrl, + }; } -}; -export async function getLatestStickerAndBackground( - dokiTheme: DokiTheme, - context: vscode.ExtensionContext -): Promise { - const localStickerPath = resolveLocalStickerPath(dokiTheme, context); - const stickerDataURL = createStickerUrl(localStickerPath); + const localStickerPath = resolveLocalStickerPath(currentTheme, context); + const localWallpaperPath = resolveLocalWallpaperPath(currentTheme, context); + await Promise.all([ + attemptToUpdateAsset(remoteStickerUrl, localStickerPath), + attemptToUpdateAsset(remoteWallpaperUrl, localWallpaperPath), + ]); + return { - stickerDataURL, - backgroundImageURL: dokiTheme.sticker.name, + stickerDataURL: createCssDokiAssetUrl(localStickerPath), + backgroundImageURL: createCssDokiAssetUrl(localWallpaperPath), }; +}; + +async function attemptToUpdateAsset( + remoteStickerUrl: string, + localStickerPath: string +) { + if (await isStickerNotCurrent(remoteStickerUrl, localStickerPath)) { + await installAsset(remoteStickerUrl, localStickerPath); + } } const fetchRemoteChecksum = async (remoteAssetUrl: string) => { @@ -49,16 +62,16 @@ const resolveLocalStickerPath = ( return path.join(context.globalStoragePath, "stickers", safeStickerPath); }; -const createStickerUrl = (localStickerPath: string): string => { - // todo: just use remote urls for code server - if (isCodeServer()) { - const base64ImageString = fs.readFileSync(localStickerPath, { - encoding: "base64", - }); - return `data:image/png;base64,${base64ImageString}`; - } +const resolveLocalWallpaperPath = ( + currentTheme: DokiTheme, + context: vscode.ExtensionContext +): string => { + const safeStickerPath = wallpaperPathToUrl(currentTheme); + return path.join(context.globalStoragePath, "wallpapers", safeStickerPath); +}; - return `file://${cleanPathToUrl(localStickerPath)}`; +const createCssDokiAssetUrl = (localAssetPath: string): string => { + return `file://${cleanPathToUrl(localAssetPath)}`; }; function cleanPathToUrl(stickerPath: string) { @@ -70,6 +83,11 @@ function stickerPathToUrl(currentTheme: DokiTheme) { return cleanPathToUrl(stickerPath); } +function wallpaperPathToUrl(currentTheme: DokiTheme) { + const stickerPath = currentTheme.sticker.name; + return cleanPathToUrl(stickerPath); +} + function createChecksum(data: Buffer | string): string { return crypto.createHash("md5").update(data).digest("hex"); } diff --git a/src/extension.ts b/src/extension.ts index bfc254b..45fc324 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,63 +1,57 @@ -import * as vscode from 'vscode'; -import { activateTheme, uninstallImages } from "./ThemeManager"; +import * as vscode from "vscode"; +import { + activateTheme, + uninstallImages, + getCurrentTheme, +} from "./ThemeManager"; import { DokiTheme } from "./DokiTheme"; -import DokiThemeDefinitions from './DokiThemeDefinitions'; -import { StatusBarComponent } from './StatusBar'; -import { VSCodeGlobals } from './VSCodeGlobals'; -import { attemptToNotifyUpdates } from './NotificationService'; -import { showChanglog } from './ChangelogService'; -import { attemptToUpdateSticker } from './StickerUpdateService'; +import DokiThemeDefinitions from "./DokiThemeDefinitions"; +import { StatusBarComponent } from "./StatusBar"; +import { VSCodeGlobals } from "./VSCodeGlobals"; +import { attemptToNotifyUpdates } from "./NotificationService"; +import { showChanglog } from "./ChangelogService"; +import { attemptToUpdateSticker } from "./StickerUpdateService"; export interface DokiThemeDefinition { - sticker: { - path: string; - name: string; - }; - information: any; + sticker: { + path: string; + name: string; + }; + information: any; } export interface VSCodeDokiThemeDefinition { - extensionName: string; - themeDefinition: DokiThemeDefinition; + extensionName: string; + themeDefinition: DokiThemeDefinition; } - export function activate(context: vscode.ExtensionContext) { - context.subscriptions.push( - vscode.commands.registerCommand( - 'extension.remove.sticker', - () => uninstallImages(context) - ) - ); - - context.subscriptions.push( - vscode.commands.registerCommand( - 'extension.doki.changelog', - () => showChanglog(context) - ) - ); - - VSCodeGlobals.globalState = context.globalState; - - StatusBarComponent.initialize(); - context.subscriptions.push(StatusBarComponent); - - attemptToNotifyUpdates(context); - - attemptToUpdateSticker(context); - - DokiThemeDefinitions - .map((dokiThemeDefinition: VSCodeDokiThemeDefinition) => - vscode.commands.registerCommand( - dokiThemeDefinition.extensionName, - () => activateTheme( - new DokiTheme(dokiThemeDefinition.themeDefinition), - context - )) - ).forEach(disposableHero => - context.subscriptions.push(disposableHero) - ); -} + context.subscriptions.push( + vscode.commands.registerCommand("extension.remove.sticker", () => + uninstallImages(context) + ) + ); + + context.subscriptions.push( + vscode.commands.registerCommand("extension.doki.changelog", () => + showChanglog(context) + ) + ); + + VSCodeGlobals.globalState = context.globalState; + StatusBarComponent.initialize(); + context.subscriptions.push(StatusBarComponent); + + attemptToNotifyUpdates(context); + + attemptToUpdateSticker(context, getCurrentTheme()); + + DokiThemeDefinitions.map((dokiThemeDefinition: VSCodeDokiThemeDefinition) => + vscode.commands.registerCommand(dokiThemeDefinition.extensionName, () => + activateTheme(new DokiTheme(dokiThemeDefinition.themeDefinition), context) + ) + ).forEach((disposableHero) => context.subscriptions.push(disposableHero)); +} -export function deactivate() { } +export function deactivate() {} From a3c4e7781c6d6f80c1c62166bf93a3198ba4e7ee Mon Sep 17 00:00:00 2001 From: DATBOI Date: Sat, 25 Apr 2020 19:48:12 -0500 Subject: [PATCH 4/6] Yay! It works! --- src/RESTClient.ts | 3 +-- src/StickerUpdateService.ts | 15 +++++++-------- src/SupportService.ts | 3 +-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/RESTClient.ts b/src/RESTClient.ts index 53418af..59d8bb7 100644 --- a/src/RESTClient.ts +++ b/src/RESTClient.ts @@ -3,8 +3,7 @@ import { Transform as Stream } from 'stream'; export const performGet = (url: string): Promise => { return new Promise((resolve, reject) => { - https.get({ - href: url, + https.get(url, { timeout: 10000, }, (res) => { const inputStream = new Stream(); diff --git a/src/StickerUpdateService.ts b/src/StickerUpdateService.ts index d098831..835430b 100644 --- a/src/StickerUpdateService.ts +++ b/src/StickerUpdateService.ts @@ -1,21 +1,20 @@ import * as vscode from "vscode"; -import { getCurrentTheme } from "./ThemeManager"; import { performGet } from "./RESTClient"; import { DokiTheme } from "./DokiTheme"; import path from "path"; import fs from "fs"; import crypto from "crypto"; -import { VSCODE_ASSETS_URL, isCodeServer } from "./ENV"; +import { VSCODE_ASSETS_URL, isCodeServer, BACKGROUND_ASSETS_URL } from "./ENV"; import { DokiStickers } from "./StickerService"; export const attemptToUpdateSticker = async ( context: vscode.ExtensionContext, - currentTheme: DokiTheme, + currentTheme: DokiTheme ): Promise => { const remoteStickerUrl = `${VSCODE_ASSETS_URL}${stickerPathToUrl( currentTheme )}`; - const remoteWallpaperUrl = `${VSCODE_ASSETS_URL}${wallpaperPathToUrl( + const remoteWallpaperUrl = `${BACKGROUND_ASSETS_URL}${wallpaperPathToUrl( currentTheme )}`; if (isCodeServer()) { @@ -42,7 +41,7 @@ async function attemptToUpdateAsset( remoteStickerUrl: string, localStickerPath: string ) { - if (await isStickerNotCurrent(remoteStickerUrl, localStickerPath)) { + if (await shouldDownloadNewAsset(remoteStickerUrl, localStickerPath)) { await installAsset(remoteStickerUrl, localStickerPath); } } @@ -84,7 +83,7 @@ function stickerPathToUrl(currentTheme: DokiTheme) { } function wallpaperPathToUrl(currentTheme: DokiTheme) { - const stickerPath = currentTheme.sticker.name; + const stickerPath = `/${currentTheme.sticker.name}`; return cleanPathToUrl(stickerPath); } @@ -103,7 +102,7 @@ const fetchLocalChecksum = async (localSticker: string) => { : "File not downloaded, bruv."; }; -const isStickerNotCurrent = async ( +const shouldDownloadNewAsset = async ( remoteAssetUrl: string, localStickerPath: string ): Promise => { @@ -127,7 +126,7 @@ const downloadRemoteAsset = async ( } console.log(`Downloading remote asset: ${remoteAssetUrl}`); const stickerInputStream = await performGet(remoteAssetUrl); - console.log("Image Downloaded!"); + console.log("Remote asset Downloaded!"); fs.writeFileSync(localDestination, stickerInputStream.read()); }; diff --git a/src/SupportService.ts b/src/SupportService.ts index 9b6ecc0..ab46439 100644 --- a/src/SupportService.ts +++ b/src/SupportService.ts @@ -1,7 +1,6 @@ import * as vscode from 'vscode'; import { getWebviewIcon, buildWebviewHtml } from "./ChangelogService"; -import { workbenchDirectory } from './StickerService'; - +import { workbenchDirectory } from './ENV'; export function showStickerInstallationSupportWindow(context: vscode.ExtensionContext) { const verbs = { From d7f38bcad404aaa6c30e615500ea98749f2eae65 Mon Sep 17 00:00:00 2001 From: DATBOI Date: Sat, 25 Apr 2020 19:55:29 -0500 Subject: [PATCH 5/6] Lints --- src/ENV.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ENV.ts b/src/ENV.ts index cf4263a..8c3af29 100644 --- a/src/ENV.ts +++ b/src/ENV.ts @@ -1,4 +1,3 @@ - import path from 'path'; import fs from "fs"; @@ -22,5 +21,4 @@ const fileName = getFileName(); export const editorCss = path.join(workbenchDirectory, `workbench.${fileName}.css`); export const editorCssCopy = path.join(workbenchDirectory, `workbench.${fileName}.css.copy`); - -export const isCodeServer = () => fileName === CODE_SERVER_FILE; \ No newline at end of file +export const isCodeServer = () => fileName === CODE_SERVER_FILE; From 9b46ee160cb426c8356b896dcf82dec8d2b9c606 Mon Sep 17 00:00:00 2001 From: DATBOI Date: Sat, 25 Apr 2020 20:02:31 -0500 Subject: [PATCH 6/6] Updated changelog and bumped version to v2.2.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/NotificationService.ts | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98370f4..8c4ec50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 2.2.0 [Offline Mode] + +- Your theme's wallpaper is now available offline! +- Small adjustments to the look and feel of the light Emilia theme. + + ## 2.1.1 [Better Update Experience] - The plugin will actually tell you if it could not install your specified sticker. diff --git a/package.json b/package.json index 218517c..66f1c31 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "The Doki Theme", "description": "Themes based on various anime and visual novel characters.", "publisher": "unthrottled", - "version": "2.1.1", + "version": "2.2.0", "license": "MIT", "icon": "Doki-Theme.png", "galleryBanner": { diff --git a/src/NotificationService.ts b/src/NotificationService.ts index 0c0ee51..41f745b 100644 --- a/src/NotificationService.ts +++ b/src/NotificationService.ts @@ -3,7 +3,7 @@ import { VSCodeGlobals } from './VSCodeGlobals'; import { attemptToGreetUser } from './WelcomeService'; const SAVED_VERSION = 'doki.theme.version'; -const DOKI_THEME_VERSION = 'v2.1.1'; +const DOKI_THEME_VERSION = 'v2.2.0'; export function attemptToNotifyUpdates(context: vscode.ExtensionContext) { const savedVersion = VSCodeGlobals.globalState.get(SAVED_VERSION);