diff --git a/CHANGELOG.md b/CHANGELOG.md
index 320a0fc..29b83cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Change Log
+# 14.1.0 [Custom Assets]
+
+Added the ability for you to add your own assets to be used by the themes!
+Please see the [README.md](https://github.com/doki-theme/doki-theme-vscode/tree/master#custom-assets) for more details.
+
+| **Custom Sticker** | **Custom Background** |
+| --- | --- |
+|  |  |
+
+| **Custom Wallpaper** |
+| --- |
+| |
+
# 14.0.0 [NekoPara Release]
## 3 New Themes!!
diff --git a/README.md b/README.md
index 593288a..c994f8e 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ You can choose themes from various, Anime, Manga, or Visual Novels:
- [Configuration](#configuration)
- [Background Images](#background-images)
- [Stickers](#sticker)
+ - [Custom Assets](#custom-assets)
- [Suggestive Content](#suggestive-content)
- [Asset Removal](#remove-assets)
- [Show Changelog](#show-changelog)
@@ -92,6 +93,53 @@ This feature will set the background image to the current theme's official wallp

+
+## Custom Assets
+
+Hey alright, you have the ability to set the image to be used for all the doki-themes. Allowed image types: jpg, png, gif. You'll have to put these changes in the `settings.json` in your VSCode.
+
+**Note**: All path values _must_ be an absolute path that resolves to a file on the machine running VSCode.
+
+**Custom Sticker**
+
+```json
+"doki.sticker.path": "C:\\Users\\alex\\Downloads\\aqua_celebration.gif",
+```
+
+
+
+**Custom Background**
+
+This is the empty editor screen (all tabs closed), the one with the VS Code watermark.
+
+```json
+"doki.background.path": "C:\\Users\\alex\\Downloads\\chocola_celebration.gif",
+```
+
+
+
+**Custom Wallpaper**
+
+This shows up on your editor and other places.
+**Note**: you'll want to make your image partially transparent.
+Cus I was too lazy to play make all the backgrounds partially transparent to show the opaque background image. Didn't feel like peeling that onion and deviating from my color schemes.
+
+```json
+"doki.wallpaper.path": "C:\\Users\\alex\\Downloads\\ishtar.png",
+```
+
+
+
+
+**Custom Wallpaper/Background Anchor**
+
+Value to be used for css 'background-position' for both the background & wallpaper (eg: center, right, left, etc.)
+
+```json
+"doki.background.anchor": "center",
+```
+
+
## Suggestive Content
diff --git a/package.json b/package.json
index 4e15650..8932b52 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"displayName": "The Doki Theme",
"description": "A bunch of themes with cute anime girls. Code with your waifu!",
"publisher": "unthrottled",
- "version": "14.0.0",
+ "version": "14.1.0",
"license": "MIT",
"icon": "Doki-Theme.png",
"galleryBanner": {
@@ -177,6 +177,33 @@
],
"main": "./out/extension.js",
"contributes": {
+ "configuration": [
+ {
+ "title": "Custom Doki Assets",
+ "properties": {
+ "doki.background.path": {
+ "type": "string",
+ "default": "",
+ "description": "Absolute file path of the image you want to use as your empty editor background."
+ },
+ "doki.background.anchor": {
+ "type": "string",
+ "default": "",
+ "description": "Value to be used for css 'background-position' for both images (eg: center, right, left, etc.)"
+ },
+ "doki.wallpaper.path": {
+ "type": "string",
+ "default": "",
+ "description": "Absolute file path of the image you want to use as your glass pane wallpaper. (Image should be transparent)"
+ },
+ "doki.sticker.path": {
+ "type": "string",
+ "default": "",
+ "description": "Absolute file path of the image you want to use as your sticker."
+ }
+ }
+ }
+ ],
"commands": [
{
"command": "doki-theme.doki.changelog",
diff --git a/readmeStuff/custom_background.gif b/readmeStuff/custom_background.gif
new file mode 100644
index 0000000..d830cc7
Binary files /dev/null and b/readmeStuff/custom_background.gif differ
diff --git a/readmeStuff/custom_sticker.gif b/readmeStuff/custom_sticker.gif
new file mode 100644
index 0000000..6781093
Binary files /dev/null and b/readmeStuff/custom_sticker.gif differ
diff --git a/readmeStuff/custom_wallpaper.png b/readmeStuff/custom_wallpaper.png
new file mode 100644
index 0000000..e922fed
Binary files /dev/null and b/readmeStuff/custom_wallpaper.png differ
diff --git a/src/ConfigWatcher.ts b/src/ConfigWatcher.ts
new file mode 100644
index 0000000..5acc2f4
--- /dev/null
+++ b/src/ConfigWatcher.ts
@@ -0,0 +1,74 @@
+import * as vscode from "vscode";
+import { InstallStatus } from "./StickerService";
+import { attemptToInstallSticker, attemptToInstallWallpaper, getCurrentThemeAndSticker, handleInstallFailure } from "./ThemeManager";
+
+export const CONFIG_NAME = "doki";
+export const CONFIG_STICKER = "sticker.path";
+export const CONFIG_BACKGROUND = "background.path";
+export const CONFIG_WALLPAPER = "wallpaper.path";
+export const CONFIG_BACKGROUND_ANCHOR = "background.anchor";
+
+let currentConfig = vscode.workspace.getConfiguration(CONFIG_NAME);
+
+export const watchConfigChanges = (
+ extensionContext: vscode.ExtensionContext
+): vscode.Disposable =>
+ vscode.workspace.onDidChangeConfiguration(() => {
+ const { sticker, theme } = getCurrentThemeAndSticker();
+ const newBoiConfig = vscode.workspace.getConfiguration(CONFIG_NAME);
+
+ const stickerInstall =
+ newBoiConfig.get(CONFIG_STICKER) !==
+ currentConfig.get(CONFIG_STICKER) ?
+ attemptToInstallSticker(sticker.sticker, extensionContext) :
+ Promise.resolve(InstallStatus.NOT_INSTALLED);
+
+ const backgroundChanged = newBoiConfig.get(CONFIG_BACKGROUND) !==
+ currentConfig.get(CONFIG_BACKGROUND);
+ const wallpaperChanged = newBoiConfig.get(CONFIG_WALLPAPER) !==
+ currentConfig.get(CONFIG_WALLPAPER);
+ const anchorChanged = newBoiConfig.get(CONFIG_BACKGROUND_ANCHOR) !==
+ currentConfig.get(CONFIG_BACKGROUND_ANCHOR);
+ const wallpaperInstall =
+ backgroundChanged || wallpaperChanged || anchorChanged ?
+ attemptToInstallWallpaper(sticker.sticker, extensionContext) :
+ Promise.resolve(InstallStatus.NOT_INSTALLED);
+
+ const installJerbs = [
+ stickerInstall,
+ wallpaperInstall,
+ ];
+ Promise.all(installJerbs)
+ .then((jerbResults) => {
+ const hadFailure = jerbResults
+ .reduce((didWork, jerbStatus) =>
+ didWork || jerbStatus == InstallStatus.FAILURE, false);
+ const hadSuccess = jerbResults
+ .reduce((didWork, jerbStatus) =>
+ didWork || jerbStatus == InstallStatus.INSTALLED, false);
+
+ if (hadFailure) {
+ handleInstallFailure(extensionContext, theme);
+ } else if (hadSuccess) {
+ vscode.window
+ .showInformationMessage(
+ `Custom Assets installed!\n Please restart your VSCode`,
+ { title: "Restart VSCode" }
+ )
+ .then((item) => {
+ if (item) {
+ vscode.commands.executeCommand("workbench.action.reloadWindow");
+ }
+ });
+ }
+ currentConfig = newBoiConfig
+ })
+ .catch(error => {
+ console.error("Unable to install custom assets for reasons", error);
+ vscode.window
+ .showInformationMessage(
+ `Oh no, I couldn't update your custom assets!\n Try again, please.`,
+ )
+ });
+ });
+
diff --git a/src/ENV.ts b/src/ENV.ts
index 6903075..24c6924 100644
--- a/src/ENV.ts
+++ b/src/ENV.ts
@@ -44,4 +44,3 @@ export const CSS_COPY_FILE_NAME = `${CSS_FILE_NAME}.copy`;
export const editorCss = path.join(workbenchDirectory, CSS_FILE_NAME);
export const editorCssCopy = path.join(workbenchDirectory, CSS_COPY_FILE_NAME);
-export const isCodeServer = () => fileName === CODE_SERVER_FILE;
diff --git a/src/NotificationService.ts b/src/NotificationService.ts
index 4a84b80..e43cb7f 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 = "v14.0.0";
+const DOKI_THEME_VERSION = "v14.1.0";
export function attemptToNotifyUpdates(context: vscode.ExtensionContext) {
const savedVersion = VSCodeGlobals.globalState.get(SAVED_VERSION);
diff --git a/src/StickerUpdateService.ts b/src/StickerUpdateService.ts
index 1e631af..1b4ad1e 100644
--- a/src/StickerUpdateService.ts
+++ b/src/StickerUpdateService.ts
@@ -6,7 +6,6 @@ import { URL } from 'url';
import crypto from "crypto";
import {
VSCODE_ASSETS_URL,
- isCodeServer,
BACKGROUND_ASSETS_URL,
isWSL,
workbenchDirectory,
@@ -14,6 +13,7 @@ import {
} from "./ENV";
import { DokiStickers } from "./StickerService";
import { Sticker } from "./extension";
+import { CONFIG_BACKGROUND, CONFIG_BACKGROUND_ANCHOR, CONFIG_NAME, CONFIG_STICKER, CONFIG_WALLPAPER } from "./ConfigWatcher";
function loadImageBase64FromFileProtocol(url: string): string {
const fileUrl = new URL(url);
@@ -53,15 +53,6 @@ const _attemptToUpdateSticker = async (
const remoteBackgroundUrl = `${BACKGROUND_ASSETS_URL}${wallpaperPathToUrl(
currentSticker
)}`;
- if (isCodeServer()) {
- return {
- stickerDataURL: remoteStickerUrl,
- backgroundImageURL: remoteBackgroundUrl,
- wallpaperImageURL: remoteWallpaperUrl,
- backgroundAnchoring: currentSticker.anchoring,
- };
- }
-
const localStickerPath = resolveLocalStickerPath(currentSticker, context);
const localWallpaperPath = resolveLocalWallpaperPath(currentSticker, context);
const localBackgroundPath = resolveLocalBackgroundPath(
@@ -74,11 +65,20 @@ const _attemptToUpdateSticker = async (
assetUpdater(remoteBackgroundUrl, localBackgroundPath, context),
]);
+ const config = vscode.workspace.getConfiguration(CONFIG_NAME);
+
return {
- stickerDataURL: createCssDokiAssetUrl(localStickerPath),
- backgroundImageURL: createCssDokiAssetUrl(localBackgroundPath),
- wallpaperImageURL: createCssDokiAssetUrl(localWallpaperPath),
- backgroundAnchoring: currentSticker.anchoring,
+ stickerDataURL: createCssDokiAssetUrl(
+ config.get(CONFIG_STICKER) || localStickerPath
+ ),
+ backgroundImageURL: createCssDokiAssetUrl(
+ config.get(CONFIG_BACKGROUND) || localBackgroundPath
+ ),
+ wallpaperImageURL: createCssDokiAssetUrl(
+ config.get(CONFIG_WALLPAPER) || localWallpaperPath
+ ),
+ backgroundAnchoring: config.get(CONFIG_BACKGROUND_ANCHOR) ||
+ currentSticker.anchoring,
};
};
@@ -94,7 +94,7 @@ async function attemptToUpdateAsset(
await forceUpdateAsset(remoteStickerUrl, localStickerPath);
}
-export class NetworkError extends Error {}
+export class NetworkError extends Error { }
async function forceUpdateAsset(
remoteStickerUrl: string,
diff --git a/src/ThemeManager.ts b/src/ThemeManager.ts
index 4deb9c4..af78325 100644
--- a/src/ThemeManager.ts
+++ b/src/ThemeManager.ts
@@ -89,7 +89,7 @@ async function attemptToInstallAsset(
}
}
-async function attemptToInstallSticker(
+export async function attemptToInstallSticker(
sticker: Sticker,
context: vscode.ExtensionContext
): Promise {
@@ -98,7 +98,7 @@ async function attemptToInstallSticker(
);
}
-async function attemptToInstallWallpaper(
+export async function attemptToInstallWallpaper(
sticker: Sticker,
context: vscode.ExtensionContext
): Promise {
@@ -179,10 +179,7 @@ export function activateThemeAsset(
}
});
} else if (didInstall === InstallStatus.FAILURE) {
- showStickerInstallationSupportWindow(context);
- vscode.window.showErrorMessage(
- `Unable to install ${dokiTheme.name}, please see active tab for more information.`
- );
+ handleInstallFailure(context, dokiTheme);
} else if (didInstall === InstallStatus.NETWORK_FAILURE) {
vscode.window.showErrorMessage(
`Unable to install ${dokiTheme.name}, please check your network connection.`
@@ -191,6 +188,13 @@ export function activateThemeAsset(
});
}
+export function handleInstallFailure(context: vscode.ExtensionContext, dokiTheme: DokiTheme) {
+ showStickerInstallationSupportWindow(context);
+ vscode.window.showErrorMessage(
+ `Unable to install ${dokiTheme.name}, please see active tab for more information.`
+ );
+}
+
// :(
export function uninstallImages(context: vscode.ExtensionContext) {
const stickersRemoved = removeStickers();
@@ -200,7 +204,7 @@ export function uninstallImages(context: vscode.ExtensionContext) {
) {
vscode.window
.showInformationMessage(
- `Removed Images. Please restart your restored IDE`,
+ `Removed Images. Please restart your restored VSCode`,
{ title: "Restart VSCode" }
)
.then((item) => {
diff --git a/src/extension.ts b/src/extension.ts
index 4dc2f1d..dbdf4d9 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -13,6 +13,7 @@ import {VSCodeGlobals} from "./VSCodeGlobals";
import {attemptToNotifyUpdates} from "./NotificationService";
import {showChanglog} from "./ChangelogService";
import {attemptToUpdateSticker} from "./StickerUpdateService";
+import { watchConfigChanges } from "./ConfigWatcher";
export interface Sticker {
path: string;
@@ -96,6 +97,8 @@ export function activate(context: vscode.ExtensionContext) {
)
)
.forEach((disposableHero) => context.subscriptions.push(disposableHero));
+
+ context.subscriptions.push(watchConfigChanges(context));
}
export function deactivate() {