opencode-avatar 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/electron.js +38 -18
  2. package/package.json +1 -1
package/dist/electron.js CHANGED
@@ -524,8 +524,8 @@ var HTML_CONTENT = `<!DOCTYPE html>
524
524
  };
525
525
  }
526
526
 
527
- ipcRenderer.on('set-avatar', (event, avatarDataUrl) => {
528
- loadAvatar(avatarDataUrl);
527
+ ipcRenderer.on('set-avatar', (event, avatarPath) => {
528
+ loadAvatar('file://' + avatarPath);
529
529
  });
530
530
 
531
531
  // Fallback: load default avatar if no IPC message received
@@ -691,10 +691,8 @@ function startAvatarServer() {
691
691
  try {
692
692
  const { avatarPath } = JSON.parse(body);
693
693
  if (mainWindow && avatarPath) {
694
- const imageBuffer = fs.readFileSync(avatarPath);
695
- const base64 = imageBuffer.toString("base64");
696
- const dataUrl = `data:image/png;base64,${base64}`;
697
- mainWindow.webContents.send("set-avatar", dataUrl);
694
+ mainWindow.webContents.send("set-avatar", avatarPath);
695
+ updateTrayIcon(avatarPath);
698
696
  }
699
697
  res.writeHead(200, { "Content-Type": "application/json" });
700
698
  res.end(JSON.stringify({ success: true }));
@@ -718,10 +716,8 @@ function startAvatarServer() {
718
716
  }
719
717
  const avatarPath = await generateAvatarForPrompt(prompt);
720
718
  if (mainWindow) {
721
- const imageBuffer = fs.readFileSync(avatarPath);
722
- const base64 = imageBuffer.toString("base64");
723
- const dataUrl = `data:image/png;base64,${base64}`;
724
- mainWindow.webContents.send("set-avatar", dataUrl);
719
+ mainWindow.webContents.send("set-avatar", avatarPath);
720
+ updateTrayIcon(avatarPath);
725
721
  }
726
722
  res.writeHead(200, { "Content-Type": "application/json" });
727
723
  res.end(JSON.stringify({ success: true, avatarPath }));
@@ -782,10 +778,8 @@ function createWindow() {
782
778
  if (mainWindow) {
783
779
  const avatarPath = getAvatarPath();
784
780
  try {
785
- const imageBuffer = fs.readFileSync(avatarPath);
786
- const base64 = imageBuffer.toString("base64");
787
- const dataUrl = `data:image/png;base64,${base64}`;
788
- mainWindow.webContents.send("set-avatar", dataUrl);
781
+ mainWindow.webContents.send("set-avatar", avatarPath);
782
+ updateTrayIcon(avatarPath);
789
783
  setTimeout(() => {
790
784
  if (mainWindow && !mainWindow.isVisible()) {
791
785
  mainWindow.show();
@@ -809,10 +803,7 @@ function createTray() {
809
803
  let trayIcon;
810
804
  try {
811
805
  const pngPath = path.join(AVATAR_DIR, "avatar.png");
812
- trayIcon = nativeImage.createFromPath(pngPath);
813
- if (trayIcon.isEmpty()) {
814
- trayIcon = nativeImage.createFromPath(path.join(AVATAR_DIR, "avatar.svg"));
815
- }
806
+ trayIcon = processTrayIcon(pngPath);
816
807
  } catch (e) {
817
808
  const message = e instanceof Error ? e.message : String(e);
818
809
  trayIcon = nativeImage.createFromPath(path.join(AVATAR_DIR, "avatar.svg"));
@@ -836,6 +827,35 @@ function createTray() {
836
827
  tray.setContextMenu(contextMenu);
837
828
  tray.on("click", () => mainWindow?.isVisible() ? mainWindow.hide() : mainWindow?.show());
838
829
  }
830
+ function processTrayIcon(pngPath) {
831
+ let trayIcon = nativeImage.createFromPath(pngPath);
832
+ if (!trayIcon.isEmpty()) {
833
+ const size = trayIcon.getSize();
834
+ const bitmap = trayIcon.getBitmap();
835
+ const chromaR = bitmap[0];
836
+ const chromaG = bitmap[1];
837
+ const chromaB = bitmap[2];
838
+ const tolerance = 30;
839
+ for (let i = 0;i < bitmap.length; i += 4) {
840
+ const r = bitmap[i];
841
+ const g = bitmap[i + 1];
842
+ const b = bitmap[i + 2];
843
+ if (Math.abs(r - chromaR) <= tolerance && Math.abs(g - chromaG) <= tolerance && Math.abs(b - chromaB) <= tolerance) {
844
+ bitmap[i + 3] = 0;
845
+ }
846
+ }
847
+ trayIcon = nativeImage.createFromBitmap(bitmap, size);
848
+ } else {
849
+ trayIcon = nativeImage.createFromPath(path.join(AVATAR_DIR, "avatar.svg"));
850
+ }
851
+ return trayIcon;
852
+ }
853
+ function updateTrayIcon(avatarPath) {
854
+ if (tray) {
855
+ const trayIcon = processTrayIcon(avatarPath);
856
+ tray.setImage(trayIcon);
857
+ }
858
+ }
839
859
  app.commandLine.appendSwitch("enable-transparent-visuals");
840
860
  app.whenReady().then(async () => {
841
861
  fs.mkdirSync(AVATAR_DIR, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-avatar",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Dynamic desktop avatar plugin for OpenCode that reacts to your coding activities",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",