diff --git a/src/index.css b/src/index.css
index 4f4b3c7..abdf9c0 100644
--- a/src/index.css
+++ b/src/index.css
@@ -43,6 +43,22 @@
--input: 214.3 31.8% 91.4%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
+
+ /* Safe area CSS variables */
+ --safe-area-inset-top: env(safe-area-inset-top);
+ --safe-area-inset-right: env(safe-area-inset-right);
+ --safe-area-inset-bottom: env(safe-area-inset-bottom);
+ --safe-area-inset-left: env(safe-area-inset-left);
+ }
+
+ /* Fallback for older iOS versions */
+ @supports (padding-top: constant(safe-area-inset-top)) {
+ :root {
+ --safe-area-inset-top: constant(safe-area-inset-top);
+ --safe-area-inset-right: constant(safe-area-inset-right);
+ --safe-area-inset-bottom: constant(safe-area-inset-bottom);
+ --safe-area-inset-left: constant(safe-area-inset-left);
+ }
}
.dark {
@@ -82,12 +98,46 @@
padding: 0;
}
- html, body, #root {
+ html, body {
height: 100%;
margin: 0;
padding: 0;
}
+ /* Root element with safe area padding for PWA */
+ #root {
+ min-height: 100vh;
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ /* Apply safe area padding in standalone mode */
+ @supports (padding-top: env(safe-area-inset-top)) {
+ @media (display-mode: standalone) {
+ #root {
+ padding-top: var(--safe-area-inset-top);
+ padding-left: var(--safe-area-inset-left);
+ padding-right: var(--safe-area-inset-right);
+ }
+ }
+ }
+
+ /* PWA mode detected by JavaScript - more reliable */
+ body.pwa-mode #root {
+ padding-top: calc(env(safe-area-inset-top, 0px) + 20px);
+ padding-left: env(safe-area-inset-left);
+ padding-right: env(safe-area-inset-right);
+ }
+
+ /* iOS specific PWA adjustments */
+ @supports (-webkit-touch-callout: none) {
+ body.pwa-mode #root {
+ /* iOS status bar is typically 20-44px */
+ padding-top: max(env(safe-area-inset-top, 44px), 44px);
+ }
+ }
+
/* Global transition defaults */
button,
a,
@@ -577,6 +627,17 @@
padding-bottom: max(env(safe-area-inset-bottom), 12px);
}
+ /* PWA specific header adjustments for iOS */
+ .pwa-header-safe {
+ padding-top: 16px;
+ }
+
+ /* When PWA mode is detected by JavaScript */
+ body.pwa-mode .pwa-header-safe {
+ /* Reset padding since #root already handles safe area */
+ padding-top: 12px;
+ }
+
@media screen and (max-width: 768px) {
.chat-input-mobile {
padding-bottom: calc(60px + max(env(safe-area-inset-bottom), 12px));
From 15b95c4d08c3add91c7a77a35c0e3d2783ba8eb5 Mon Sep 17 00:00:00 2001
From: simos
Date: Mon, 15 Sep 2025 15:56:33 +0000
Subject: [PATCH 2/4] Fixing maximum depth of directories
---
server/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/index.js b/server/index.js
index d69f825..f6553b8 100755
--- a/server/index.js
+++ b/server/index.js
@@ -506,7 +506,7 @@ app.get('/api/projects/:projectName/files', authenticateToken, async (req, res)
return res.status(404).json({ error: `Project path not found: ${actualPath}` });
}
- const files = await getFileTree(actualPath, 3, 0, true);
+ const files = await getFileTree(actualPath, 10, 0, true);
const hiddenFiles = files.filter(f => f.name.startsWith('.'));
res.json(files);
} catch (error) {
From fb1117a99989f9c78d17ef2e266a71d04655f5c3 Mon Sep 17 00:00:00 2001
From: simos
Date: Mon, 15 Sep 2025 20:31:33 +0000
Subject: [PATCH 3/4] Fix: Fixed mobile zoom on input
---
index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/index.html b/index.html
index 8ee3437..a0f807c 100644
--- a/index.html
+++ b/index.html
@@ -4,7 +4,7 @@
-
+
Claude Code UI
From 79981693f3cfd26a700b4e9651803aa08e653e27 Mon Sep 17 00:00:00 2001
From: simos
Date: Mon, 15 Sep 2025 20:57:49 +0000
Subject: [PATCH 4/4] Fix : mobile issues and git diff in the git panel
---
server/projects.js | 16 +++++--------
src/App.jsx | 4 +++-
src/components/DiffViewer.jsx | 41 ++++++++++++++++++++++++++++++++++
src/components/GitPanel.jsx | 28 ++++-------------------
src/components/MainContent.jsx | 3 ---
src/index.css | 40 +++++++++++++++++++++++++--------
6 files changed, 84 insertions(+), 48 deletions(-)
create mode 100644 src/components/DiffViewer.jsx
diff --git a/server/projects.js b/server/projects.js
index 3f0b2b5..4f0aae3 100755
--- a/server/projects.js
+++ b/server/projects.js
@@ -899,22 +899,16 @@ async function addProjectManually(projectPath, displayName = null) {
// Generate project name (encode path for use as directory name)
const projectName = absolutePath.replace(/\//g, '-');
- // Check if project already exists in config or as a folder
+ // Check if project already exists in config
const config = await loadProjectConfig();
const projectDir = path.join(process.env.HOME, '.claude', 'projects', projectName);
-
- try {
- await fs.access(projectDir);
- throw new Error(`Project already exists for path: ${absolutePath}`);
- } catch (error) {
- if (error.code !== 'ENOENT') {
- throw error;
- }
- }
-
+
if (config[projectName]) {
throw new Error(`Project already configured for path: ${absolutePath}`);
}
+
+ // Allow adding projects even if the directory exists - this enables tracking
+ // existing Claude Code or Cursor projects in the UI
// Add to config as manually added project
config[projectName] = {
diff --git a/src/App.jsx b/src/App.jsx
index 82bb91a..b20afb4 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -89,10 +89,12 @@ function AppContent() {
document.referrer.includes('android-app://');
setIsPWA(isStandalone);
- // Add class to body for CSS targeting
+ // Add class to html and body for CSS targeting
if (isStandalone) {
+ document.documentElement.classList.add('pwa-mode');
document.body.classList.add('pwa-mode');
} else {
+ document.documentElement.classList.remove('pwa-mode');
document.body.classList.remove('pwa-mode');
}
};
diff --git a/src/components/DiffViewer.jsx b/src/components/DiffViewer.jsx
new file mode 100644
index 0000000..a624c0b
--- /dev/null
+++ b/src/components/DiffViewer.jsx
@@ -0,0 +1,41 @@
+import React from 'react';
+
+function DiffViewer({ diff, fileName, isMobile, wrapText }) {
+ if (!diff) {
+ return (
+
+ No diff available
+
+ );
+ }
+
+ const renderDiffLine = (line, index) => {
+ const isAddition = line.startsWith('+') && !line.startsWith('+++');
+ const isDeletion = line.startsWith('-') && !line.startsWith('---');
+ const isHeader = line.startsWith('@@');
+
+ return (
+
+ {line}
+
+ );
+ };
+
+ return (
+
+ {diff.split('\n').map((line, index) => renderDiffLine(line, index))}
+
+ );
+}
+
+export default DiffViewer;
\ No newline at end of file
diff --git a/src/components/GitPanel.jsx b/src/components/GitPanel.jsx
index b71d2ef..5962d29 100644
--- a/src/components/GitPanel.jsx
+++ b/src/components/GitPanel.jsx
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useRef } from 'react';
import { GitBranch, GitCommit, Plus, Minus, RefreshCw, Check, X, ChevronDown, ChevronRight, Info, History, FileText, Mic, MicOff, Sparkles, Download, RotateCcw, Trash2, AlertTriangle, Upload } from 'lucide-react';
import { MicButton } from './MicButton.jsx';
import { authenticatedFetch } from '../utils/api';
+import DiffViewer from './DiffViewer.jsx';
function GitPanel({ selectedProject, isMobile }) {
const [gitStatus, setGitStatus] = useState(null);
@@ -523,27 +524,6 @@ function GitPanel({ selectedProject, isMobile }) {
}
};
- const renderDiffLine = (line, index) => {
- const isAddition = line.startsWith('+') && !line.startsWith('+++');
- const isDeletion = line.startsWith('-') && !line.startsWith('---');
- const isHeader = line.startsWith('@@');
-
- return (
-
- {line}
-
- );
- };
const getStatusLabel = (status) => {
switch (status) {
@@ -590,7 +570,7 @@ function GitPanel({ selectedProject, isMobile }) {
{commit.stats}
- {diff.split('\n').map((line, index) => renderDiffLine(line, index))}
+