@setoelkahfi / svara / commits / 8bdeb28

feat: Add Recent folders popup

Billy committed Oct 12, 2024 at 00:55 UTC 8bdeb288057c9e722d469a61d01cf0a93ea82b2b
2 files changed +168 -3
src/lib/Welcome.svelte
+13 -3
@@ -1,18 +1,25 @@
1 <script lang="ts">
2 - import { openFolder } from "./File";
2 + import { openFolderDialog } from "./File";
3 import { DocumentBlank, Folder, RecentlyViewed, Settings } from "carbon-icons-svelte";
4 import { addEditorTab, addTab } from "./EditorTabList.svelte";
5 import settings from "./Settings.svelte";
6 import { getVersion } from '@tauri-apps/api/app';
7 import { onMount } from "svelte";
8 + import RecentFolders from "./utility/RecentFolders.svelte";
9
10 export let hidden = true;
11
12 let appVersion = "";
13 + let showRecentFolders = false;
14
15 onMount(async () => {
16 appVersion = await getVersion();
17 })
18 +
19 + function toggleRecentFolders() {
20 + console.log("toggleRecentFolders");
21 + showRecentFolders = !showRecentFolders;
22 + }
23 </script>
24
25 <div class="container" class:hidden>
@@ -23,8 +30,11 @@
30
31 <div class="quick-actions">
32 <button on:click={() => addEditorTab()} ><DocumentBlank /> New file</button>
26 - <button on:click={openFolder} ><Folder /> Open Folder</button>
27 - <!-- <button on:click={openFolder} ><RecentlyViewed /> Recent...</button> -->
33 + <button on:click={openFolderDialog} ><Folder /> Open Folder</button>
34 + <button on:click={toggleRecentFolders} ><RecentlyViewed /> Recent...</button>
35 + {#if showRecentFolders}
36 + <RecentFolders on:close={toggleRecentFolders} />
37 + {/if}
38 <button on:click={() => addTab("Settings", "Settings", new settings({target: document.getElementById("tabview")}))}><Settings /> Settings</button>
39 </div>
40 </div>
src/lib/utility/RecentFolders.svelte new
+155
@@ -0,0 +1,155 @@
1 +<script lang="ts">
2 + import { createEventDispatcher, onMount } from 'svelte';
3 + import { openFolder } from '../File';
4 +
5 + let recentFolders: string[] = [];
6 + let filteredFolders: string[] = [];
7 + let searchTerm = '';
8 + let selectedIndex = 0;
9 + const dispatch = createEventDispatcher();
10 +
11 + onMount(async () => {
12 + console.log("RecentFoldersPopup mounted");
13 +
14 + let data = localStorage.getItem("recentFolders");
15 + if (data) {
16 + recentFolders = JSON.parse(data);
17 + filteredFolders = [...recentFolders];
18 + } else {
19 + recentFolders = [];
20 + filteredFolders = [];
21 + }
22 + });
23 +
24 + function handleKeydown(event: KeyboardEvent) {
25 + if (event.key === 'Escape') {
26 + console.log("Escape key pressed");
27 + dispatch('close');
28 + } else if (event.key === 'ArrowDown') {
29 + selectedIndex = (selectedIndex + 1) % filteredFolders.length;
30 + event.preventDefault();
31 + } else if (event.key === 'ArrowUp') {
32 + selectedIndex = (selectedIndex - 1 + filteredFolders.length) % filteredFolders.length;
33 + event.preventDefault();
34 + } else if (event.key === 'Enter') {
35 + handleFolderClick(filteredFolders[selectedIndex]);
36 + }
37 + }
38 +
39 + function handleFolderClick(folder: string) {
40 + openFolder(folder);
41 + dispatch('close');
42 + }
43 +
44 + $: {
45 + filteredFolders = recentFolders.filter(folder =>
46 + folder.toLowerCase().includes(searchTerm.toLowerCase())
47 + );
48 + selectedIndex = 0;
49 + }
50 +</script>
51 +
52 +<svelte:window on:keydown={handleKeydown} />
53 +
54 +<div class="overlay" on:click={() => dispatch('close')}>
55 + <div class="popup" on:click|stopPropagation>
56 + <input
57 + type="text"
58 + bind:value={searchTerm}
59 + placeholder="Search recent folders..."
60 + autofocus
61 + />
62 + {#if filteredFolders.length === 0}
63 + <p>No matching folders</p>
64 + {:else}
65 + <ul>
66 + {#each filteredFolders as folder, index}
67 + <li class:selected={index === selectedIndex}>
68 + <button on:click={() => handleFolderClick(folder)}>
69 + {folder}
70 + </button>
71 + </li>
72 + {/each}
73 + </ul>
74 + {/if}
75 + </div>
76 +</div>
77 +
78 +<style lang="scss">
79 + .overlay {
80 + position: fixed;
81 + top: 0;
82 + left: 0;
83 + width: 100%;
84 + height: 100%;
85 + display: flex;
86 + justify-content: center;
87 + align-items: flex-start;
88 + padding-top: 10vh;
89 + z-index: 1000;
90 + }
91 +
92 + .popup {
93 + border-radius: 8px;
94 + padding: 10px;
95 + width: 80%;
96 + max-width: 600px;
97 + max-height: 80vh;
98 + overflow-y: auto;
99 + background: rgba(30, 30, 30, 0.90);
100 + backdrop-filter: blur(5px);
101 + -webkit-backdrop-filter: blur(5px);
102 + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
103 + }
104 +
105 + input {
106 + width: 100%;
107 + padding: 10px;
108 + margin-bottom: 10px;
109 + background: rgba(60, 60, 60, 0.5);
110 + border: none;
111 + border-radius: 4px;
112 + color: white;
113 + font-size: 16px;
114 + }
115 +
116 + input:focus {
117 + outline: none;
118 + box-shadow: 0 0 0 2px #006FF2;
119 + }
120 +
121 + ul {
122 + list-style: none;
123 + padding: 0;
124 + margin: 0;
125 + }
126 +
127 + li {
128 + margin-bottom: 5px;
129 + }
130 +
131 + li.selected {
132 + background-color: rgba(0, 111, 242, 0.2);
133 + border-radius: 4px;
134 + }
135 +
136 + button {
137 + width: 100%;
138 + text-align: left;
139 + padding: 8px;
140 + background: none;
141 + border: none;
142 + color: white;
143 + cursor: pointer;
144 + transition: background-color 0.2s;
145 + }
146 +
147 + button:hover {
148 + background-color: rgba(255, 255, 255, 0.1);
149 + }
150 +
151 + p {
152 + color: #888;
153 + text-align: center;
154 + }
155 +</style>
\ No newline at end of file