Skip to content

Commit b1e41ca

Browse files
committed
fix: worktree refresh + terminal link & ctrl+maj+c handling
1 parent 3f196ab commit b1e41ca

4 files changed

Lines changed: 298 additions & 232 deletions

File tree

app/app.vue

Lines changed: 187 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,187 @@
1-
<template>
2-
<div>
3-
<div class="bg" />
4-
<div class="bg bg2" />
5-
<div class="bg bg3" />
6-
<div class="screen">
7-
<NuxtPage />
8-
</div>
9-
10-
<Transition name="loader-fade">
11-
<div v-if="loading" class="loader-overlay">
12-
<div class="loader-card">
13-
<img src="/logo.svg" alt="LoCode" class="loader-logo" />
14-
<div class="loader-text-container">
15-
<span v-for="i in messages.length" class="loader-text"
16-
:style="{ animationDelay: `${(i - 1) * 2}s` }">
17-
{{ messages[(messageIndex + i) % messages.length]! }}
18-
</span>
19-
</div>
20-
<div class="loader-progress">
21-
<div class="loader-progress-fill" />
22-
</div>
23-
</div>
24-
</div>
25-
</Transition>
26-
</div>
27-
</template>
28-
29-
<style lang="css" scoped>
30-
.screen {
31-
width: 100%;
32-
height: 100%;
33-
position: fixed;
34-
}
35-
36-
.bg {
37-
filter: blur(2px);
38-
animation: slide 12s ease-in-out infinite alternate;
39-
background-image: linear-gradient(-60deg, #09f 50%, #6c3 50%);
40-
position: fixed;
41-
left: -50%;
42-
right: -50%;
43-
top: 0;
44-
bottom: 0;
45-
opacity: 0.5;
46-
}
47-
48-
.bg2 {
49-
animation-delay: -3s;
50-
animation-direction: alternate-reverse;
51-
animation-duration: 16s;
52-
}
53-
54-
.bg3 {
55-
animation-delay: -6s;
56-
animation-duration: 20s;
57-
}
58-
59-
@keyframes slide {
60-
0% { transform: translateX(-25%); }
61-
100% { transform: translateX(25%); }
62-
}
63-
64-
/* --- Loading overlay --- */
65-
.loader-overlay {
66-
position: fixed;
67-
inset: 0;
68-
z-index: 9999;
69-
display: flex;
70-
align-items: center;
71-
justify-content: center;
72-
backdrop-filter: blur(20px);
73-
-webkit-backdrop-filter: blur(20px);
74-
background: rgba(0, 0, 0, 0.3);
75-
}
76-
77-
.loader-card {
78-
display: flex;
79-
flex-direction: column;
80-
align-items: center;
81-
gap: 20px;
82-
padding: 40px 50px;
83-
background: rgba(20, 20, 20, 0.6);
84-
border: 1px solid rgba(255, 255, 255, 0.1);
85-
border-radius: 16px;
86-
box-shadow:
87-
0 8px 32px rgba(0, 0, 0, 0.4),
88-
inset 0 1px 0 rgba(255, 255, 255, 0.05);
89-
}
90-
91-
.loader-logo {
92-
width: 48px;
93-
height: 48px;
94-
animation: logo-pulse 1.995s ease-in-out infinite;
95-
}
96-
97-
@keyframes logo-pulse {
98-
0%, 100% { opacity: 0.7; transform: scale(1); }
99-
40%, 60% { opacity: 1; transform: scale(1.08); }
100-
}
101-
102-
.loader-text-container {
103-
height: 22px;
104-
list-style: none;
105-
overflow: hidden;
106-
}
107-
108-
.loader-text {
109-
font-size: 0.85rem;
110-
font-weight: 500;
111-
color: rgba(255, 255, 255, 0.95);
112-
white-space: nowrap;
113-
letter-spacing: 0.02em;
114-
position: absolute;
115-
opacity: 0;
116-
animation: rotate 20s infinite;
117-
transform: translateX(-50%)
118-
}
119-
120-
@keyframes rotate {
121-
0%, 10% { opacity: 0 }
122-
3%, 7% { opacity: 1 }
123-
}
124-
125-
.loader-progress {
126-
width: 180px;
127-
height: 2px;
128-
border-radius: 2px;
129-
background: rgba(255, 255, 255, 0.08);
130-
overflow: hidden;
131-
}
132-
133-
.loader-progress-fill {
134-
height: 100%;
135-
border-radius: 2px;
136-
background: linear-gradient(90deg, rgba(100, 180, 255, 0.6), rgba(100, 220, 180, 0.6));
137-
animation: progress-indeterminate 5s cubic-bezier(0.4, 0, 0.2, 1);
138-
}
139-
140-
@keyframes progress-indeterminate {
141-
0% { width: 0% }
142-
20% { width: 70% }
143-
80% { width: 95% }
144-
100% { width: 100% }
145-
}
146-
147-
/* --- Loader fade out --- */
148-
.loader-fade-leave-active {
149-
transition: opacity 0.4s ease;
150-
}
151-
.loader-fade-leave-to {
152-
opacity: 0;
153-
}
154-
</style>
155-
156-
<script setup lang="ts">
157-
useHead({
158-
title: "LoCode",
159-
meta: [
160-
{ name: "viewport", content: "width=device-width, initial-scale=1, interactive-widget=resizes-content" },
161-
]
162-
});
163-
164-
const messages = [
165-
// "Activation du mode turbo",
166-
"Déploiement de la matrice syntaxique",
167-
"Harmonisation des fréquences binaires",
168-
"Optimisation des particules virtuelles",
169-
"Compilation des algorithmes quantiques",
170-
"Calibration de l'interface holographique",
171-
"Chargement des bibliothèques neurales",
172-
"Injection du code source galactique",
173-
"Synchronisation des flux temporels",
174-
"Chargement des shaders cognitifs",
175-
"Analyse spectrale du workspace",
176-
// "Initialisation du plasma",
177-
];
178-
179-
const loading = ref(true);
180-
// useState: computed once on server, serialized in HTML payload, reused as-is on client → no hydration mismatch
181-
const messageIndex = useState('loaderMsgIdx', () => Math.floor(Math.random() * messages.length));
182-
183-
onMounted(() => {
184-
nextTick(() => { loading.value = false; });
185-
});
186-
187-
</script>
1+
<template>
2+
<div>
3+
<div class="bg" />
4+
<div class="bg bg2" />
5+
<div class="bg bg3" />
6+
<div class="screen">
7+
<NuxtPage />
8+
</div>
9+
10+
<Transition name="loader-fade">
11+
<div v-if="loading" class="loader-overlay">
12+
<div class="loader-card">
13+
<img src="/logo.svg" alt="LoCode" class="loader-logo" />
14+
<div class="loader-text-container">
15+
<span v-for="i in messages.length" class="loader-text"
16+
:style="{ animationDelay: `${(i - 1) * 2}s` }">
17+
{{ messages[(messageIndex + i) % messages.length]! }}
18+
</span>
19+
</div>
20+
<div class="loader-progress">
21+
<div class="loader-progress-fill" />
22+
</div>
23+
</div>
24+
</div>
25+
</Transition>
26+
</div>
27+
</template>
28+
29+
<style lang="css" scoped>
30+
.screen {
31+
width: 100%;
32+
height: 100%;
33+
position: fixed;
34+
}
35+
36+
.bg {
37+
filter: blur(2px);
38+
animation: slide 12s ease-in-out infinite alternate;
39+
background-image: linear-gradient(-60deg, #09f 50%, #6c3 50%);
40+
position: fixed;
41+
left: -50%;
42+
right: -50%;
43+
top: 0;
44+
bottom: 0;
45+
opacity: 0.5;
46+
}
47+
48+
.bg2 {
49+
animation-delay: -3s;
50+
animation-direction: alternate-reverse;
51+
animation-duration: 16s;
52+
}
53+
54+
.bg3 {
55+
animation-delay: -6s;
56+
animation-duration: 20s;
57+
}
58+
59+
@keyframes slide {
60+
0% { transform: translateX(-25%); }
61+
100% { transform: translateX(25%); }
62+
}
63+
64+
/* --- Loading overlay --- */
65+
.loader-overlay {
66+
position: fixed;
67+
inset: 0;
68+
z-index: 9999;
69+
display: flex;
70+
align-items: center;
71+
justify-content: center;
72+
backdrop-filter: blur(20px);
73+
-webkit-backdrop-filter: blur(20px);
74+
background: rgba(0, 0, 0, 0.3);
75+
}
76+
77+
.loader-card {
78+
display: flex;
79+
flex-direction: column;
80+
align-items: center;
81+
gap: 20px;
82+
padding: 40px 50px;
83+
background: rgba(20, 20, 20, 0.6);
84+
border: 1px solid rgba(255, 255, 255, 0.1);
85+
border-radius: 16px;
86+
box-shadow:
87+
0 8px 32px rgba(0, 0, 0, 0.4),
88+
inset 0 1px 0 rgba(255, 255, 255, 0.05);
89+
}
90+
91+
.loader-logo {
92+
width: 48px;
93+
height: 48px;
94+
animation: logo-pulse 1.995s ease-in-out infinite;
95+
}
96+
97+
@keyframes logo-pulse {
98+
0%, 100% { opacity: 0.7; transform: scale(1); }
99+
40%, 60% { opacity: 1; transform: scale(1.08); }
100+
}
101+
102+
.loader-text-container {
103+
height: 22px;
104+
list-style: none;
105+
overflow: hidden;
106+
}
107+
108+
.loader-text {
109+
font-size: 0.85rem;
110+
font-weight: 500;
111+
color: rgba(255, 255, 255, 0.95);
112+
white-space: nowrap;
113+
letter-spacing: 0.02em;
114+
position: absolute;
115+
opacity: 0;
116+
animation: rotate 20s infinite;
117+
transform: translateX(-50%)
118+
}
119+
120+
@keyframes rotate {
121+
0%, 10% { opacity: 0 }
122+
3%, 7% { opacity: 1 }
123+
}
124+
125+
.loader-progress {
126+
width: 180px;
127+
height: 2px;
128+
border-radius: 2px;
129+
background: rgba(255, 255, 255, 0.08);
130+
overflow: hidden;
131+
}
132+
133+
.loader-progress-fill {
134+
height: 100%;
135+
border-radius: 2px;
136+
background: linear-gradient(90deg, #09f, #6c3);/* rgba(100, 180, 255, 0.6), rgba(100, 220, 180, 0.6)); */
137+
animation: progress-indeterminate 5s cubic-bezier(0.4, 0, 0.2, 1);
138+
}
139+
140+
@keyframes progress-indeterminate {
141+
0% { width: 0% }
142+
20% { width: 70% }
143+
80% { width: 95% }
144+
100% { width: 100% }
145+
}
146+
147+
/* --- Loader fade out --- */
148+
.loader-fade-leave-active {
149+
transition: opacity 0.4s ease;
150+
}
151+
.loader-fade-leave-to {
152+
opacity: 0;
153+
}
154+
</style>
155+
156+
<script setup lang="ts">
157+
useHead({
158+
title: "LoCode",
159+
meta: [
160+
{ name: "viewport", content: "width=device-width, initial-scale=1, interactive-widget=resizes-content" },
161+
]
162+
});
163+
164+
const messages = [
165+
// "Activation du mode turbo",
166+
"Déploiement de la matrice syntaxique",
167+
"Harmonisation des fréquences binaires",
168+
"Optimisation des particules virtuelles",
169+
"Compilation des algorithmes quantiques",
170+
"Calibration de l'interface holographique",
171+
"Chargement des bibliothèques neurales",
172+
"Injection du code source galactique",
173+
"Synchronisation des flux temporels",
174+
"Chargement des shaders cognitifs",
175+
"Analyse spectrale du workspace",
176+
// "Initialisation du plasma",
177+
];
178+
179+
const loading = ref(true);
180+
// useState: computed once on server, serialized in HTML payload, reused as-is on client → no hydration mismatch
181+
const messageIndex = useState('loaderMsgIdx', () => Math.floor(Math.random() * messages.length));
182+
183+
onMounted(() => {
184+
nextTick(() => { loading.value = false; });
185+
});
186+
187+
</script>

0 commit comments

Comments
 (0)