Compare commits

...

4 Commits

Author SHA1 Message Date
580ec5ab0d Notifications accept. 2025-03-05 17:52:18 +01:00
578c182f27 Notifications accept. 2025-03-05 17:51:25 +01:00
c3c94461c2 Update service worker. 2025-03-05 17:19:24 +01:00
45e3239cc0 Upload changes. 2025-03-03 00:35:08 +01:00
6 changed files with 57 additions and 4 deletions

View File

@ -1,9 +1,20 @@
from snek.system.service import BaseService
from snek.system.model import now
class NotificationService(BaseService):
mapper_name = "notification"
async def mark_as_read(self, user_uid, channel_message_uid):
model = await self.get(user_uid, object_uid=channel_message_uid)
if not model:
return False
model['read_at'] = now()
await self.save(model)
return True
async def get_unread_stats(self,user_uid):
records = await self.query("SELECT object_type, COUNT(*) as count FROM notification WHERE user_uid=:user_uid AND read_at IS NULL GROUP BY object_type",dict(user_uid=user_uid))
async def create(self, object_uid, object_type, user_uid, message):
model = await self.new()
model["object_uid"] = object_uid

View File

@ -1,3 +1,37 @@
async function requestNotificationPermission() {
const permission = await Notification.requestPermission();
return permission === 'granted';
}
// Subscribe to Push Notifications
async function subscribeUser() {
const registration = await navigator.serviceWorker.register('/service-worker.js');
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(PUBLIC_VAPID_KEY)
});
// Send subscription to your backend
await fetch('/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: {
'Content-Type': 'application/json'
}
});
}
// Service Worker (service-worker.js)
self.addEventListener('push', event => {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.message,
icon: data.icon
});
});
/*
self.addEventListener("install", (event) => {
console.log("Service worker installed");
});
@ -27,4 +61,4 @@ self.addEventListener("notificationclick", (event) => {
event.notification.close();
event.waitUntil(clients.openWindow(
"https://snek.molodetz.nl",));
});
});*/

View File

@ -73,7 +73,7 @@ def set_link_target_blank(text):
element.attrs['target'] = '_blank'
element.attrs['rel'] = 'noopener noreferrer'
element.attrs['referrerpolicy'] = 'no-referrer'
element.attrs['href'] = element.attrs['href'].strip(".")
element.attrs['href'] = element.attrs['href'].strip(".").strip(",")
return str(soup)

View File

@ -39,6 +39,11 @@ class RPCView(BaseView):
def is_logged_in(self):
return self.view.session.get("logged_in", False)
async def mark_as_read(self, message_uid):
self._require_login()
await self.services.notification.mark_as_read(self.user_uid, message_uid)
return True
async def login(self, username, password):
success = await self.services.user.validate_login(username, password)
if not success:

View File

@ -77,7 +77,7 @@ class UploadView(BaseView):
await self.services.drive_item.save(drive_item)
response = "Uploaded [" + filename + "](/drive.bin/" + drive_item["uid"] + ")"
#response = "<iframe width=\"100%\" frameborder=\"0\" allowfullscreen title=\"Embedded\" src=\"" + self.base_url + "/drive.bin/" + drive_item["uid"] + "\"></iframe>\n"
response = "[url](/drive.bin/" + drive_item["uid"] + extension + ")"
response = "[" + filename + "](/drive.bin/" + drive_item["uid"] + extension + ")"
await self.services.chat.send(
self.request.session.get("uid"), channel_uid, response

View File

@ -46,6 +46,9 @@ class WebView(BaseView):
messages = [await self.app.services.channel_message.to_extended_dict(message) for message in await self.app.services.channel_message.offset(
channel["uid"]
)]
for message in messages:
await self.app.services.notification.mark_as_read(self.session.get("uid"),message["uid"])
channels = []
async for subscribed_channel in self.app.services.channel_member.find(user_uid=self.session.get("uid"), deleted_at=None, is_banned=False):
item = {}