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,12 +1,12 @@
/* each star */
.star {
position: absolute;
width: 2px;
height: 2px;
background: #fff;
background: var(--star-color, #fff);
border-radius: 50%;
opacity: 0;
/* flicker animation */
transition: background 0.5s ease;
animation: twinkle ease-in-out infinite;
}
@ -15,14 +15,28 @@
50% { opacity: 1; }
}
/* optional page content */
@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: #eee;
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>
<script type="module">
import { app } from "/app.js";
// number of stars you want
const STAR_COUNT = 200;
const body = document.body;
for (let i = 0; i < STAR_COUNT; i++) {
function createStar() {
const star = document.createElement('div');
star.classList.add('star');
// random position within the viewport
star.style.left = Math.random() * 100 + '%';
star.style.top = Math.random() * 100 + '%';
// random size (optional)
const size = Math.random() * 2 + 1; // between 1px and 3px
star.style.width = size + 'px';
star.style.height = size + 'px';
// 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';
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);
}
Array.from({ length: STAR_COUNT }, createStar);
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)}`;
}
const originalColor = document.documentElement.style.getPropertyValue("--star-color").trim();
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
}
})