master
svelte 218 lines 7.23 KB
Raw
1 <script lang="ts">
2 import { isfile } from "./EditorTabList.svelte";
3 import { line_info, language, encoding, spaces } from "./Editor.svelte";
4 import { getVersion } from '@tauri-apps/api/app';
5 import { onMount } from "svelte";
6 import { Terminal as TerminalIcon, Notification as NotificationIcon, TrashCan } from "carbon-icons-svelte";
7 import { invoke } from "@tauri-apps/api";
8 import Terminal, { clearTerminal, closeTerminal } from "./Terminal.svelte";
9 import { workingDir } from "./File";
10 import NotificationList from "./Notifications/NotificationList.svelte";
11 import { clearNotifications, markAllRead, unreadnotifications } from "./Notifications/notifications";
12
13 let appVersion = "";
14 onMount(async () => {
15 appVersion = await getVersion();
16 })
17
18 const tools = [
19 {name: "Terminal", content: Terminal, icon: TerminalIcon, action: (t) => {spawnTerminal(t)}, options: [
20 {name: "Clear Terminal", action: () => {clearTerminal();}},
21 {name: "Close Terminal", action: () => {
22 closeBottomPanel();
23 closeTerminal();
24 }}
25 ]},
26 {name: "Notifications", content: NotificationList, icon: NotificationIcon, action: (t) => {toggleBottomPanel(t)}, options: [
27 {name: "Mark all as Read", action: () => {markAllRead()}}],
28 buttons: [
29 {icon: TrashCan, title: "Clear Notifications", action: () => {clearNotifications()}}
30 ]}
31 ]
32
33 async function spawnTerminal(t) {
34 if ($externalTerminal) {
35 invoke("open_terminal", {path: $workingDir});
36 }
37 else {
38 toggleBottomPanel(t);
39 }
40 }
41 </script>
42 <script lang="ts" context="module">
43 import { get, writable } from "svelte/store";
44 export let showBottomPanel = writable(false);
45 export let externalTerminal = writable(false);
46 let lastTool = writable({tool: null, element: null});
47 let activeTools: {tool: any, element: any}[] = [];
48 let show = false;
49
50 export let editortool = writable({name: "", options: [], buttons: []});
51
52 export function toggleBottomPanel(tool = null) {
53 let last = get(lastTool);
54 if (tool === last.tool) {
55 show = !show;
56 showBottomPanel.set(show);
57 return;
58 }
59 if (activeTools.length === 0) {
60 let element = new tool.content({target: document.getElementById("toolview-container")});
61 lastTool.set({tool: tool, element: element});
62 activeTools = [...activeTools, {tool: tool, element: element}];
63 show = true;
64 showBottomPanel.set(true);
65 }
66 else {
67 let mountedTool = activeTools.find(f => f.tool === tool);
68 if (!mountedTool) {
69 if (last.element) {
70 last.element.$set({hidden: true});
71 }
72 let element = new tool.content({target: document.getElementById("toolview-container")});
73 lastTool.set({tool: tool, element: element});
74 activeTools = [...activeTools, {tool: tool, element: element}];
75 show = true;
76 showBottomPanel.set(true);
77 }
78 else {
79 if (last.element) {
80 last.element.$set({hidden: true});
81 mountedTool.element.$set({hidden: false});
82 lastTool.set(mountedTool);
83 showBottomPanel.set(true);
84 }
85 }
86 }
87
88 if (tool) {
89 editortool.set({name: tool.name, options: tool.options, buttons: tool.buttons});
90 }
91 }
92 export function hideBottomPanel() {
93 show = false;
94 showBottomPanel.set(false);
95 }
96 export function closeBottomPanel() {
97 show = false;
98 showBottomPanel.set(false);
99 let current = activeTools.find(t => t.tool.name === get(editortool).name);
100 if (current) current.element.$destroy();
101 activeTools = activeTools.filter(t => t.tool.name !== get(editortool).name);
102 editortool.set({name: "", options: [], buttons: []});
103 lastTool.set({tool: null, element: null});
104 }
105 export function setTerminalState(value) {
106 let v = value === true ? true : false;
107 externalTerminal.set(v);
108 }
109 </script>
110
111 <div id="statusbar">
112 <div id="title">
113 <span>Svara <span id="version">v{appVersion}-alpha</span></span>
114 <div class="divider"></div>
115 </div>
116 <div class="editor-tools">
117 {#each tools as tool}
118 <!-- svelte-ignore a11y-click-events-have-key-events -->
119 <span class="tool" title={tool.name} on:click={() => {tool.action(tool)}} class:updated={$unreadnotifications}>
120 <svelte:component this={tool.icon}></svelte:component>
121 {#if tool.name === "Notifications"}
122 <span class="notification"></span>
123 {/if}
124 </span>
125 {/each}
126 </div>
127 {#if $isfile}
128 <div class="editor-info">
129 <span title="Indentation">Spaces: {$spaces}</span>
130 <div class="divider"></div>
131 <span title="Ln: {$line_info.line}, Col: {$line_info.column}">{$line_info.line} : {$line_info.column}</span>
132 <div class="divider"></div>
133 <span>{$encoding.value} {$encoding.hasBom === true ? " with BOM" : ""}</span>
134 <div class="divider"></div>
135 <span>{$language}</span>
136 </div>
137 {/if}
138 </div>
139
140 <style lang="scss">
141 #statusbar {
142 z-index: 8000;
143 width: -webkit-fill-available;
144 display: flex;
145 align-items: center;
146 font-size: 0.9rem;
147 :global(span svg) {
148 width: 20px;
149 height: 20px;
150 }
151 }
152 #title {
153 display: flex;
154 justify-content: flex-start;
155 align-items: center;
156 height: 100%;
157 span {
158 height: 100%;
159 padding: 0 10px;
160 }
161 }
162 .divider {
163 width: 0.0625rem;
164 height: 1rem;
165 }
166 .editor-tools {
167 height: 100%;
168 display: flex;
169 align-items: center;
170 justify-content: flex-start;
171 padding-left: 10px;
172 .tool {
173 height: 100%;
174 padding: 0 5px;
175 position: relative;
176 &:hover {
177 cursor: pointer;
178 }
179 &.updated {
180 .notification {
181 position: absolute;
182 width: 8px;
183 height: 8px;
184 display: block;
185 background-color: #4589ff;
186 border-radius: 50%;
187 top: 5px;
188 right: 5px;
189 border: none;
190 }
191 }
192 }
193 span {
194 display: flex;
195 align-items: center;
196 justify-content: center;
197 }
198 }
199 .editor-info {
200 display: flex;
201 justify-content: flex-end;
202 align-items: center;
203 flex-grow: 1;
204 font-size: 13px;
205 height: 100%;
206 span {
207 padding: 0 7px;
208 height: 100%;
209 display: flex;
210 align-items: center;
211 }
212 }
213 #version {
214 font-size: 0.7rem;
215 padding: 0 !important;
216 color: #6d6d6d;
217 }
218 </style>