Skip to content

Commit d46c75c

Browse files
Add docs and GitHub links to welcome screen
1 parent 5ed4fd7 commit d46c75c

File tree

9 files changed

+132
-27
lines changed

9 files changed

+132
-27
lines changed

src-tauri/capabilities/main.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
"http:allow-fetch",
5353
"process:allow-restart",
5454
"process:allow-exit",
55+
"shell:default",
56+
"shell:allow-open",
5557
{
5658
"identifier": "shell:allow-execute",
5759
"allow": [

src-tauri/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ fn main() {
130130
"open_folder" => {
131131
let _ = window.emit("menu_open_folder", ());
132132
}
133+
"close_folder" => {
134+
let _ = window.emit("menu_close_folder", ());
135+
}
133136
"save" => {
134137
let _ = window.emit("menu_save", ());
135138
}

src-tauri/src/menu.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ pub fn create_menu<R: tauri::Runtime>(
4242
true,
4343
Some("CmdOrCtrl+O"),
4444
)?)
45+
.item(&MenuItem::with_id(
46+
app,
47+
"close_folder",
48+
"Close Folder",
49+
true,
50+
None::<String>,
51+
)?)
4552
.separator()
4653
.item(&MenuItem::with_id(
4754
app,

src/components/window/menu-bar/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const CustomMenuBar = ({ activeMenu, setActiveMenu }: Props) => {
3333
<MenuItem shortcut="Ctrl+O" onClick={() => handleClickEmit("menu_open_folder")}>
3434
Open Folder
3535
</MenuItem>
36+
<MenuItem onClick={() => handleClickEmit("menu_close_folder")}>Close Folder</MenuItem>
3637
<MenuItem separator />
3738
<MenuItem shortcut="Ctrl+S" onClick={() => handleClickEmit("menu_save")}>
3839
Save

src/components/window/welcome-screen.tsx

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { AlertCircle, Download, Folder } from "lucide-react";
1+
import { AlertCircle, Book, Download, Folder, Github, Settings } from "lucide-react";
22
import { useEffect, useState } from "react";
33
import Button from "@/components/ui/button";
4+
import SettingsDialog from "@/settings/components/settings-dialog";
45
import { useUpdater } from "@/settings/hooks/use-updater";
6+
import { useUIState } from "@/stores/ui-state-store";
57
import { fetchRawAppVersion } from "@/utils/app-utils";
68

7-
// ...existing code...
8-
99
interface RecentFolder {
1010
name: string;
1111
path: string;
@@ -24,6 +24,10 @@ const WelcomeScreen = ({
2424
onOpenRecentFolder,
2525
}: WelcomeScreenProps) => {
2626
const [appVersion, setAppVersion] = useState<string>("...");
27+
const { openSettingsDialog, isSettingsDialogVisible, setIsSettingsDialogVisible } = useUIState();
28+
29+
// Hide updater in development environment
30+
const isDevelopment = import.meta.env.MODE === "development";
2731
const {
2832
available,
2933
checking,
@@ -33,7 +37,7 @@ const WelcomeScreen = ({
3337
updateInfo,
3438
downloadAndInstall,
3539
dismissUpdate,
36-
} = useUpdater(true);
40+
} = useUpdater(!isDevelopment);
3741

3842
useEffect(() => {
3943
const loadVersion = async () => {
@@ -52,6 +56,10 @@ const WelcomeScreen = ({
5256
}
5357
};
5458

59+
const openExternalLink = (url: string) => {
60+
window.open(url, "_blank", "noopener,noreferrer");
61+
};
62+
5563
return (
5664
<div
5765
data-tauri-drag-region
@@ -63,14 +71,14 @@ const WelcomeScreen = ({
6371
<img src="/logo.svg" alt="athas industries" className="h-12" draggable="false" />
6472
</div>
6573
<div className="flex items-center gap-2 text-text-lighter">
66-
<p className="font-mono font-normal text-xs">v{appVersion}</p>
67-
{checking && (
68-
<div className="text-xs" title="Checking for updates...">
74+
<p className="font-mono text-xs">v{appVersion}</p>
75+
{!isDevelopment && checking && (
76+
<div className="animate-spin text-xs" title="Checking...">
6977
7078
</div>
7179
)}
72-
{available && (
73-
<div className="text-accent text-xs" title={`Update available: ${updateInfo?.version}`}>
80+
{!isDevelopment && available && (
81+
<div className="text-accent text-xs" title={`Update: ${updateInfo?.version}`}>
7482
7583
</div>
7684
)}
@@ -80,28 +88,30 @@ const WelcomeScreen = ({
8088
{/* Main Content */}
8189
<div className="flex w-full max-w-sm flex-col items-center px-4">
8290
{/* Update Available Banner */}
83-
{available && (
91+
{!isDevelopment && available && (
8492
<div className="mb-4 w-full">
85-
<div className="rounded-md border border-border p-3 text-text">
93+
<div className="rounded-md border border-border p-3">
8694
<div className="mb-2 flex items-center gap-2">
8795
<Download size={14} className="text-accent" />
88-
<span className="font-mono text-xs">Update Available</span>
96+
<span className="font-mono text-text text-xs">Update Available</span>
8997
</div>
90-
<p className="mb-3 font-mono text-xs">
91-
Version {updateInfo?.version} is ready to install
92-
</p>
98+
<p className="mb-3 font-mono text-text-light text-xs">v{updateInfo?.version} ready</p>
9399
<div className="flex gap-2">
94100
<Button
95101
onClick={downloadAndInstall}
96102
disabled={downloading || installing}
97103
variant="ghost"
98-
className="flex-1 gap-2 bg-secondary-bg py-1 text-xs transition-all duration-200"
104+
className="flex-1 gap-1 bg-secondary-bg py-1 text-xs"
99105
size="sm"
100106
>
101107
{downloading ? (
102-
"⟳ Downloading"
108+
<>
109+
<div className="animate-spin"></div> Download
110+
</>
103111
) : installing ? (
104-
"⟳ Installing"
112+
<>
113+
<div className="animate-spin"></div> Install
114+
</>
105115
) : (
106116
<>
107117
<Download size={12} />
@@ -112,7 +122,7 @@ const WelcomeScreen = ({
112122
<Button
113123
onClick={dismissUpdate}
114124
variant="ghost"
115-
className="bg-secondary-bg px-2 py-1 text-xs transition-all duration-200"
125+
className="bg-secondary-bg px-2 py-1 text-xs"
116126
size="sm"
117127
>
118128
Later
@@ -123,10 +133,10 @@ const WelcomeScreen = ({
123133
)}
124134

125135
{/* Error Banner */}
126-
{error && (
136+
{!isDevelopment && error && (
127137
<div className="mb-4 w-full">
128138
<div className="rounded-md border border-error p-3">
129-
<div className="flex items-center gap-2 ">
139+
<div className="flex items-center gap-2">
130140
<AlertCircle size={14} className="text-error" />
131141
<span className="font-mono text-text text-xs">Update Error</span>
132142
</div>
@@ -140,29 +150,31 @@ const WelcomeScreen = ({
140150
<Button
141151
onClick={onOpenFolder}
142152
variant="ghost"
143-
className="flex gap-2 border border-border bg-secondary-bg p-4 text-sm transition-all duration-200"
153+
className="flex gap-2 border border-border bg-secondary-bg px-4 py-3 text-xs"
144154
size="sm"
145155
>
146-
<Folder size={16} />
156+
<Folder size={14} />
147157
Open Folder
148158
</Button>
149159
</div>
150160

151161
{/* Recent Folders */}
152162
{recentFolders.length > 0 && (
153163
<div className="w-full">
154-
<h3 className="mb-2 font-mono text-text text-xs">Recent({recentFolders.length})</h3>
164+
<h3 className="mb-2 font-mono text-text text-xs">Recent ({recentFolders.length})</h3>
155165
<div className="space-y-1.5">
156166
{recentFolders.map((folder, index) => (
157167
<Button
158168
key={index}
159169
onClick={() => handleRecentFolderClick(folder.path)}
160170
variant="ghost"
161-
className="flex h-auto w-full flex-col justify-start gap-2 border border-border bg-secondary-bg p-2 transition-all duration-200"
171+
className="flex h-auto w-full flex-col justify-start gap-1.5 border border-border bg-secondary-bg p-2"
162172
size="sm"
163173
>
164-
<div className="w-full truncate text-start font-mono text-sm">{folder.name}</div>
165-
<div className="w-full text-start">
174+
<div className="w-full truncate text-left font-mono text-text text-xs">
175+
{folder.name}
176+
</div>
177+
<div className="w-full text-left">
166178
<p className="font-mono text-text-lighter text-xs">
167179
{folder.path.startsWith("/Users/")
168180
? `~${folder.path.substring(folder.path.indexOf("/", 7))}`
@@ -174,7 +186,50 @@ const WelcomeScreen = ({
174186
</div>
175187
</div>
176188
)}
189+
190+
{/* Quick Links */}
191+
<div className="mt-6 flex w-full justify-center gap-4">
192+
<button
193+
onClick={() => openSettingsDialog()}
194+
className="flex items-center gap-1 text-text-lighter transition-colors hover:text-text"
195+
>
196+
<Settings size={14} />
197+
<span className="text-xs">Settings</span>
198+
</button>
199+
<a
200+
href="https://docs.athas.dev"
201+
target="_blank"
202+
rel="noopener noreferrer"
203+
onClick={(e) => {
204+
e.preventDefault();
205+
openExternalLink("https://docs.athas.dev");
206+
}}
207+
className="flex items-center gap-1 text-text-lighter transition-colors hover:text-text"
208+
>
209+
<Book size={14} />
210+
<span className="text-xs">Docs</span>
211+
</a>
212+
<a
213+
href="https://github.com/athasdev/athas"
214+
target="_blank"
215+
rel="noopener noreferrer"
216+
onClick={(e) => {
217+
e.preventDefault();
218+
openExternalLink("https://github.com/athasdev/athas");
219+
}}
220+
className="flex items-center gap-1 text-text-lighter transition-colors hover:text-text"
221+
>
222+
<Github size={14} />
223+
<span className="text-xs">GitHub</span>
224+
</a>
225+
</div>
177226
</div>
227+
228+
{/* Settings Dialog */}
229+
<SettingsDialog
230+
isOpen={isSettingsDialogVisible}
231+
onClose={() => setIsSettingsDialogVisible(false)}
232+
/>
178233
</div>
179234
);
180235
};

src/file-system/controllers/store.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,39 @@ export const useFileSystemStore = createSelectors(
106106
return true;
107107
},
108108

109+
closeFolder: async () => {
110+
// Reset all project-related state to return to welcome screen
111+
set((state) => {
112+
state.files = [];
113+
state.isFileTreeLoading = false;
114+
state.filesVersion++;
115+
});
116+
117+
// Clear tree UI state
118+
useFileTreeStore.getState().collapseAll();
119+
120+
// Reset project store
121+
const { setRootFolderPath, setProjectName } = useProjectStore.getState();
122+
setRootFolderPath("");
123+
setProjectName("");
124+
125+
// Close all buffers (close them individually since closeAllBuffers doesn't exist)
126+
const { buffers, actions: bufferActions } = useBufferStore.getState();
127+
buffers.forEach((buffer) => bufferActions.closeBuffer(buffer.id));
128+
129+
// Stop file watching
130+
await useFileWatcherStore.getState().setProjectRoot("");
131+
132+
// Reset git store
133+
const { actions: gitActions } = useGitStore.getState();
134+
gitActions.resetCommits();
135+
136+
// Clear git diff cache
137+
gitDiffCache.clear();
138+
139+
return true;
140+
},
141+
109142
handleOpenFolderByPath: async (path: string) => {
110143
set((state) => {
111144
state.isFileTreeLoading = true;

src/file-system/models/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export interface FsActions {
2424
// Folder operations
2525
handleOpenFolder: () => Promise<boolean>;
2626
handleOpenFolderByPath: (path: string) => Promise<boolean>;
27+
closeFolder: () => Promise<boolean>;
2728
// File operations
2829
handleFileSelect: (
2930
path: string,

src/hooks/use-menu-events-wrapper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export function useMenuEventsWrapper() {
2424
useMenuEvents({
2525
onNewFile: fileSystemStore.handleCreateNewFile,
2626
onOpenFolder: fileSystemStore.handleOpenFolder,
27+
onCloseFolder: fileSystemStore.closeFolder,
2728
onSave: handleSave,
2829
onSaveAs: async () => {
2930
if (!activeBuffer) return;

src/hooks/use-menu-events.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ async function setupMenuListeners(handlers: any) {
2727
const removeListeners = await Promise.all([
2828
listen("menu_new_file", () => currentHandlers.current.onNewFile()),
2929
listen("menu_open_folder", () => currentHandlers.current.onOpenFolder()),
30+
listen("menu_close_folder", () => currentHandlers.current.onCloseFolder()),
3031
listen("menu_save", () => currentHandlers.current.onSave()),
3132
listen("menu_save_as", () => currentHandlers.current.onSaveAs()),
3233
listen("menu_close_tab", () => currentHandlers.current.onCloseTab()),
@@ -63,6 +64,7 @@ async function setupMenuListeners(handlers: any) {
6364
interface UseMenuEventsProps {
6465
onNewFile: () => void;
6566
onOpenFolder: () => void;
67+
onCloseFolder: () => void;
6668
onSave: () => void;
6769
onSaveAs: () => void;
6870
onCloseTab: () => void;

0 commit comments

Comments
 (0)