Skip to content

Commit d3d31e0

Browse files
authored
Merge pull request #55 from Qwiri/develop
2 parents 0baebee + 5c6cb4e commit d3d31e0

File tree

3 files changed

+101
-14
lines changed

3 files changed

+101
-14
lines changed

frontend/public/global.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ a {
2121
a:hover {
2222
text-decoration: underline;
2323
}
24+
::-webkit-scrollbar {
25+
width: 12px;
26+
overflow-y: hidden;
27+
}
28+
::-webkit-scrollbar-track {
29+
background-color: transparent;
30+
}
31+
::-webkit-scrollbar-thumb {
32+
background-color: #d6dee1;
33+
/* background-color: transparent; */
34+
border-radius: 20px;
35+
border: 4px solid transparent;
36+
background-clip: content-box;
37+
}
38+
::-webkit-scrollbar-thumb:hover {
39+
background-color: #a8bbbf;
40+
border: 2px solid transparent;
41+
background-clip: content-box;
42+
}
2443

2544
a:visited {
2645
color: rgb(0,80,160);

frontend/src/assets/Chat.svelte

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
22
import { toast } from "@zerodevx/svelte-toast";
3+
import { afterUpdate, beforeUpdate } from "svelte";
34
45
import { chatMessages, ws } from "../store";
56
import Avatar from "./Avatar.svelte";
@@ -18,21 +19,40 @@
1819
$ws.send(`CHAT ${buffer}`);
1920
buffer = "";
2021
};
22+
23+
let chatElement: HTMLElement;
24+
let shouldAutoScroll = true;
25+
26+
afterUpdate(() => {
27+
if (shouldAutoScroll) {
28+
chatElement.scrollIntoView(false);
29+
}
30+
});
31+
32+
function onScroll() {
33+
const elem = document.getElementById("chat-messages");
34+
shouldAutoScroll = (elem.scrollHeight - elem.scrollTop) - 60
35+
<= elem.clientHeight; // 20px grace
36+
}
2137
</script>
2238

2339
<div>
2440
<div id="chatContainer">
25-
<ul>
26-
{#each $chatMessages as message}
27-
<li>
28-
<Avatar user={message.author} width="24px" />
29-
<span class="author">{message.author}</span>:
30-
<span class="message">{message.message}</span>
31-
</li>
32-
{/each}
33-
</ul>
41+
<div id="messageContainer">
42+
<ul on:scroll={onScroll} id="chat-messages">
43+
{#each $chatMessages as message}
44+
<li>
45+
<Avatar user={message.author} width="24px" />
46+
<span class="author">{message.author}</span>:
47+
<span class="message">{message.message}</span>
48+
</li>
49+
{/each}
50+
<div id="scrollMe" bind:this={chatElement} />
51+
</ul>
52+
</div>
3453
<input
3554
placeholder="Write a chat message"
55+
class="gyf-bar"
3656
type="text"
3757
on:keypress={onKeyDown}
3858
bind:value={buffer}
@@ -54,10 +74,18 @@
5474
flex-direction: column-reverse;
5575
}
5676
}
77+
78+
#messageContainer {
79+
position: relative;
80+
}
81+
5782
ul {
5883
padding: 0;
5984
display: flex;
6085
flex-direction: column;
86+
max-height: 35vh;
87+
overflow-y: scroll;
88+
scroll-snap-align: end;
6189
@media (max-width: 40rem) {
6290
flex-direction: column-reverse;
6391
}

frontend/src/screens/SearchGif.svelte

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
1313
let submission: string = "";
1414
15+
let gifPreviewWindow: HTMLImageElement;
16+
let gifPreviewURL: string;
17+
18+
let blur = false;
19+
1520
const fetchFirstGifs = async () => {
1621
searchResults = []; // #42
1722
searchResults = await provider.search(searchQuery, true);
@@ -42,7 +47,6 @@
4247
let timer;
4348
4449
const debounce = (e: KeyboardEvent) => {
45-
4650
if (e.key === "Enter") {
4751
return;
4852
}
@@ -52,6 +56,15 @@
5256
await fetchFirstGifs();
5357
}, 300);
5458
};
59+
60+
const previewGif = (e: MouseEvent, gif?: SearchResult) => {
61+
gifPreviewURL = gif?.original_url ?? "";
62+
63+
if (gifPreviewWindow) {
64+
gifPreviewWindow.style.left = e.pageX + "px";
65+
gifPreviewWindow.style.top = e.pageY + "px";
66+
}
67+
};
5568
</script>
5669

5770
<TopicDisplay />
@@ -70,7 +83,7 @@
7083
type="text"
7184
class="gyf-bar"
7285
placeholder="Search via {provider.name} 🔍"
73-
on:keyup="{debounce}"
86+
on:keyup={debounce}
7487
bind:value={searchQuery}
7588
/>
7689

@@ -83,11 +96,24 @@
8396
/>
8497
{/if}
8598
</div>
86-
<div id="resultWrapper">
99+
{#if gifPreviewURL}
100+
<img
101+
id="gifPreviewWindow"
102+
bind:this={gifPreviewWindow}
103+
src={gifPreviewURL}
104+
alt="GYF preview"
105+
class:blurImage={blur}
106+
on:load={(_) => (blur = false)}
107+
/>
108+
{/if}
109+
110+
<div id="resultWrapper" on:mouseleave={(e) => previewGif(e, undefined)}>
87111
{#if searchResults.length > 0}
88112
{#each searchResults as result}
89113
<div
90114
class="imgContainer"
115+
on:mousemove={(e) => previewGif(e, result)}
116+
on:mouseleave={(_) => (blur = true)}
91117
on:click={(e) => submitGif(e, result)}
92118
>
93119
<Image
@@ -130,6 +156,17 @@
130156
overflow-y: scroll;
131157
}
132158
159+
#gifPreviewWindow {
160+
position: absolute;
161+
z-index: 1;
162+
pointer-events: none;
163+
width: 30rem;
164+
height: 30rem;
165+
object-fit: contain;
166+
background-color: #181818;
167+
border-radius: 0.5rem;
168+
}
169+
133170
button {
134171
background-color: #24ff00;
135172
border: none;
@@ -151,12 +188,15 @@
151188
background-color: #181818;
152189
overflow: hidden;
153190
154-
:global(.imageComponent):hover {
191+
&:hover {
155192
cursor: pointer;
156-
opacity: 0.5;
157193
}
158194
}
159195
196+
.blurImage {
197+
filter: blur(10px);
198+
}
199+
160200
#shownProvider {
161201
color: greenyellow;
162202

0 commit comments

Comments
 (0)