This commit is contained in:
retoor 2025-05-19 01:07:11 +02:00
parent 527b010b24
commit db5431d77d
5 changed files with 101 additions and 53 deletions

View File

@ -55,6 +55,7 @@ from snek.view.upload import UploadView
from snek.view.user import UserView
from snek.view.web import WebView
from snek.view.channel import ChannelAttachmentView
from snek.view.settings.containers import ContainersIndexView, ContainersCreateView, ContainersUpdateView, ContainersDeleteView
from snek.webdav import WebdavApplication
from snek.sgit import GitApplication
SESSION_KEY = b"c79a0c5fda4b424189c427d28c9f7c34"
@ -208,6 +209,10 @@ class Application(BaseApplication):
self.router.add_view("/settings/repositories/create.html", RepositoriesCreateView)
self.router.add_view("/settings/repositories/repository/{name}/update.html", RepositoriesUpdateView)
self.router.add_view("/settings/repositories/repository/{name}/delete.html", RepositoriesDeleteView)
self.router.add_view("/settings/containers/index.html", ContainersIndexView)
self.router.add_view("/settings/containers/create.html", ContainersCreateView)
self.router.add_view("/settings/containers/container/{uid}/update.html", ContainersUpdateView)
self.router.add_view("/settings/containers/container/{uid}/delete.html", ContainersDeleteView)
self.webdav = WebdavApplication(self)
self.git = GitApplication(self)
self.add_subapp("/webdav", self.webdav)

View File

@ -53,7 +53,8 @@ class ChatInputComponent extends HTMLElement {
this.textarea.focus();
}
connectedCallback() {
async connectedCallback() {
this.user = await app.rpc.getUser(null);
this.liveType = this.getAttribute("live-type") === "true";
this.liveTypeInterval = parseInt(this.getAttribute("live-type-interval")) || 3;
this.channelUid = this.getAttribute("channel");
@ -193,7 +194,7 @@ class ChatInputComponent extends HTMLElement {
if (this.trackSecondsBetweenEvents(this.lastUpdateEvent, new Date()) > 1) {
this.lastUpdateEvent = new Date();
if (typeof app !== "undefined" && app.rpc && typeof app.rpc.set_typing === "function") {
app.rpc.set_typing(this.channelUid);
app.rpc.set_typing(this.channelUid,this.user.color);
}
}
}

View File

@ -1,28 +1,42 @@
/* each star */
.star {
position: absolute;
width: 2px;
height: 2px;
background: #fff;
border-radius: 50%;
opacity: 0;
/* flicker animation */
animation: twinkle ease-in-out infinite;
}
@keyframes twinkle {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
.star {
position: absolute;
width: 2px;
height: 2px;
background: var(--star-color, #fff);
border-radius: 50%;
opacity: 0;
transition: background 0.5s ease;
animation: twinkle ease-in-out infinite;
}
/* optional page content */
.content {
position: relative;
z-index: 1;
color: #eee;
font-family: sans-serif;
text-align: center;
top: 40%;
transform: translateY(-40%);
}
@keyframes twinkle {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
@keyframes star-glow-frames {
0% {
box-shadow: 0 0 5px --star-color;
}
50% {
box-shadow: 0 0 20px --star-color, 0 0 30px --star-color;
}
100% {
box-shadow: 0 0 5px --star-color;
}
}
.star-glow {
animation: star-glow-frames 1s;
}
.content {
position: relative;
z-index: 1;
color: var(--star-content-color, #eee);
font-family: sans-serif;
text-align: center;
top: 40%;
transform: translateY(-40%);
}

View File

@ -1,31 +1,56 @@
<script>
// number of stars you want
const STAR_COUNT = 200;
const body = document.body;
<script type="module">
import { app } from "/app.js";
for (let i = 0; i < STAR_COUNT; i++) {
const star = document.createElement('div');
star.classList.add('star');
const STAR_COUNT = 200;
const body = document.body;
// random position within the viewport
star.style.left = Math.random() * 100 + '%';
star.style.top = Math.random() * 100 + '%';
function createStar() {
const star = document.createElement('div');
star.classList.add('star');
star.style.left = `${Math.random() * 100}%`;
star.style.top = `${Math.random() * 100}%`;
const size = Math.random() * 2 + 1;
star.style.width = `${size}px`;
star.style.height = `${size}px`;
const duration = Math.random() * 3 + 2;
const delay = Math.random() * 5;
star.style.animationDuration = `${duration}s`;
star.style.animationDelay = `${delay}s`;
body.appendChild(star);
}
// random size (optional)
const size = Math.random() * 2 + 1; // between 1px and 3px
star.style.width = size + 'px';
star.style.height = size + 'px';
Array.from({ length: STAR_COUNT }, createStar);
// random animation timing for natural flicker
const duration = Math.random() * 3 + 2; // 2s5s
const delay = Math.random() * 5; // 0s5s
star.style.animationDuration = duration + 's';
star.style.animationDelay = delay + 's';
function lightenColor(hex, percent) {
const num = parseInt(hex.replace("#", ""), 16);
let r = (num >> 16) + Math.round(255 * percent / 100);
let g = ((num >> 8) & 0x00FF) + Math.round(255 * percent / 100);
let b = (num & 0x0000FF) + Math.round(255 * percent / 100);
r = Math.min(255, r);
g = Math.min(255, g);
b = Math.min(255, b);
return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`;
}
body.appendChild(star);
}
const originalColor = document.documentElement.style.getPropertyValue("--star-color").trim();
</script>
function glowCSSVariable(varName, glowColor, duration = 500) {
const root = document.documentElement;
//igetComputedStyle(root).getPropertyValue(varName).trim();
glowColor = lightenColor(glowColor, 20);
root.style.setProperty(varName, glowColor);
setTimeout(() => {
root.style.setProperty(varName, originalColor);
}, duration);
}
function updateStarColorDelayed(color) {
glowCSSVariable('--star-color', color, 2500);
}
app.ws.addEventListener("set_typing", (data) => {
updateStarColorDelayed(data.data.color);
});
</script>

View File

@ -36,9 +36,11 @@ class RPCView(BaseView):
async def db_update(self, table_name, record):
self._require_login()
return await self.services.db.update(self.user_uid, table_name, record)
async def set_typing(self,channel_uid):
async def set_typing(self,channel_uid,color=None):
self._require_login()
user = await self.services.user.get(self.user_uid)
if not color:
color = user["color"]
return await self.services.socket.broadcast(channel_uid, {
"channel_uid": "293ecf12-08c9-494b-b423-48ba1a2d12c2",
"event": "set_typing",
@ -47,7 +49,8 @@ class RPCView(BaseView):
"user_uid": user['uid'],
"username": user["username"],
"nick": user["nick"],
"channel_uid": channel_uid
"channel_uid": channel_uid,
"color": color
}
})