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