From 38fa59e5bbd8a60c523dd11ffdaee68fa7674a1e Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 27 Jul 2026 00:17:17 +0000 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20dcrypt=20app=20icon=20=E2=80=94=20w?= =?UTF-8?q?indow/dock=20icon=20from=20resources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/resources/icon.png | Bin 0 -> 23704 bytes apps/desktop/resources/icon.svg | 18 ++++++++++++++++++ apps/desktop/src/main/index.ts | 11 ++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 apps/desktop/resources/icon.png create mode 100644 apps/desktop/resources/icon.svg diff --git a/apps/desktop/resources/icon.png b/apps/desktop/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..92a6400e2b8db4863dc7cf1c18cc73cce4da85b7 GIT binary patch literal 23704 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 literal 0 HcmV?d00001 diff --git a/apps/desktop/resources/icon.svg b/apps/desktop/resources/icon.svg new file mode 100644 index 0000000..c965741 --- /dev/null +++ b/apps/desktop/resources/icon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 56a2eb1..f293fe5 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -1,4 +1,4 @@ -import { app, BrowserWindow, powerMonitor, session, shell } from 'electron'; +import { app, BrowserWindow, nativeImage, powerMonitor, session, shell } from 'electron'; import * as path from 'path'; import { CHANNELS } from '../shared/api'; @@ -7,6 +7,10 @@ import { VaultService } from './vault-service'; const DEV_SERVER_URL = process.env.ELECTRON_RENDERER_URL; +const APP_ICON = nativeImage.createFromPath( + path.join(__dirname, '../../resources/icon.png') +); + const service = new VaultService(); /** Minutes of user idle time before the vault locks itself. */ @@ -27,6 +31,7 @@ const createWindow = (): BrowserWindow => { minHeight: 600, show: false, autoHideMenuBar: true, + icon: APP_ICON, webPreferences: { preload: path.join(__dirname, '../preload/index.js'), contextIsolation: true, @@ -90,6 +95,10 @@ app.whenReady().then(() => { callback({ cancel: !allowed }); }); + if (process.platform === 'darwin' && !APP_ICON.isEmpty()) { + app.dock?.setIcon(APP_ICON); + } + registerIpc(service); mainWindow = createWindow(); watchIdle(); From 74edbe012b3d019fae26c2f7d41155e0da940d61 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 27 Jul 2026 00:22:13 +0000 Subject: [PATCH 2/2] feat: animated cube-stack loader for unlock and first-time database setup --- .../src/renderer/src/components/Loader.tsx | 73 +++++++++++++++++++ .../src/renderer/src/screens/UnlockScreen.tsx | 19 +++++ 2 files changed, 92 insertions(+) create mode 100644 apps/desktop/src/renderer/src/components/Loader.tsx diff --git a/apps/desktop/src/renderer/src/components/Loader.tsx b/apps/desktop/src/renderer/src/components/Loader.tsx new file mode 100644 index 0000000..45ca075 --- /dev/null +++ b/apps/desktop/src/renderer/src/components/Loader.tsx @@ -0,0 +1,73 @@ +const KEYFRAMES = [0, 1, 2, 3, 4, 5] + .map( + (i) => ` +@keyframes dcrypt-cube${i} { + 0%, ${(i * 8.57).toFixed(1)}% { + transform: translateY(${-220 - i * 40}px); + opacity: 0; + } + ${(35.7 + i * 8.57).toFixed(1)}%, 100% { + transform: translateY(0); + opacity: 1; + } +} +.dcrypt-cube-${i} { + animation: dcrypt-cube${i} 1.4s cubic-bezier(0.65, 0, 0.35, 1) infinite alternate; + transform-origin: center; +}` + ) + .join('\n'); + +const CUBES: [string, string, string][] = [ + [ + 'M103.923 300 L207.846 360 L207.846 480 L103.923 420 Z', + 'M311.769 300 L207.846 360 L207.846 480 L311.769 420 Z', + 'M207.846 240 L311.769 300 L207.846 360 L103.923 300 Z', + ], + [ + 'M0 360 L103.923 420 L103.923 540 L0 480 Z', + 'M207.846 360 L103.923 420 L103.923 540 L207.846 480 Z', + 'M103.923 300 L207.846 360 L103.923 420 L0 360 Z', + ], + [ + 'M103.923 -60 L207.846 0 L207.846 120 L103.923 60 Z', + 'M311.769 -60 L207.846 0 L207.846 120 L311.769 60 Z', + 'M207.846 -120 L311.769 -60 L207.846 0 L103.923 -60 Z', + ], + [ + 'M-103.923 300 L0 360 L0 480 L-103.923 420 Z', + 'M103.923 300 L0 360 L0 480 L103.923 420 Z', + 'M0 240 L103.923 300 L0 360 L-103.923 300 Z', + ], + [ + 'M0 0 L103.923 60 L103.923 180 L0 120 Z', + 'M207.846 0 L103.923 60 L103.923 180 L207.846 120 Z', + 'M103.923 -60 L207.846 0 L103.923 60 L0 0 Z', + ], + [ + 'M-103.923 180 L0 240 L0 360 L-103.923 300 Z', + 'M103.923 180 L0 240 L0 360 L103.923 300 Z', + 'M0 120 L103.923 180 L0 240 L-103.923 180 Z', + ], +]; + +/** The animated dcrypt cube-stack loader. */ +export const Loader = ({ className }: { className?: string }) => ( + + + {CUBES.map((paths, i) => ( + + {paths.map((d, j) => ( + + ))} + + ))} + +); diff --git a/apps/desktop/src/renderer/src/screens/UnlockScreen.tsx b/apps/desktop/src/renderer/src/screens/UnlockScreen.tsx index 3c3aec6..bf6ee24 100644 --- a/apps/desktop/src/renderer/src/screens/UnlockScreen.tsx +++ b/apps/desktop/src/renderer/src/screens/UnlockScreen.tsx @@ -12,6 +12,7 @@ import { Label } from '@constructive-io/ui/label'; import { ShieldCheck } from 'lucide-react'; import { FormEvent, useEffect, useState } from 'react'; +import { Loader } from '../components/Loader'; import { dcrypt } from '../lib/ipc'; export const UnlockScreen = ({ onUnlocked }: { onUnlocked: () => void }) => { @@ -58,6 +59,24 @@ export const UnlockScreen = ({ onUnlocked }: { onUnlocked: () => void }) => { const creating = exists === false; + if (busy) { + return ( +
+ +
+

+ {creating ? 'Setting up your encrypted database…' : 'Unlocking your vault…'} +

+

+ {creating + ? 'Deploying the local database and sealing it under your master password. This first run takes a little longer.' + : 'Deriving your key and loading the encrypted database.'} +

+
+
+ ); + } + return (