Finish Notifications -> Conversation

This commit is contained in:
2026-05-25 09:55:47 +02:00
parent a778222564
commit 250509055b
11 changed files with 238 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ import "easymde/dist/easymde.min.css";
import { calculate as calculateHashes } from "./hashes.js";
import hovercard from "./hovercard.js";
import notifications from "./notifications.js";
import conversations from "./conversations.js";
// Lucide icons.
@@ -27,3 +28,6 @@ Alpine.store('hovercard', hovercard() );
// Notifications
Alpine.store('notifications', notifications() );
// Conversations
Alpine.store('conversations', conversations() );

View File

@@ -0,0 +1,103 @@
/** @typedef { import('types/ConversationResponseItem.js').ConversationResponseItem} ConversationResponseItem */
export default function conversations() {
return {
/**
* @type {boolean}
*/
start: false,
/**
* @type {ConversationResponseItem[]}
*/
data: null,
/**
* @type {boolean}
*/
loading: false,
/**
* @type {boolean}
*/
error: false,
/**
* @type {number}
*/
unviewed: 0,
/**
* Request for getting notifications.
*
* @return {Promise<void>}
*/
async getConversations() {
if( this.loading )
return;
this.loading = true;
this.error = false;
try {
const RESPONSE = await fetch('/api/dynamic/conversations', { credentials: "include", headers: { 'X-Requested-With': 'XMLHttpRequest' } });
if( !RESPONSE.ok )
throw new Error(RESPONSE.status)
let json = await RESPONSE.json()
if( !json.conversations )
throw new Error(RESPONSE.status);
this.data = json.conversations;
} catch (error) {
this.error = true;
} finally {
this.loading = false;
}
},
/**
*
* @param {HTMLElement} anchorEl
* @return {Promise<void>}
*/
async open( anchorEl ){
if( this.start ){
this.close();
return;
}
this.start = !this.start;
if( this.start && !this.data ){
await this.getConversations();
}
if( this.start ){
Alpine.nextTick(() => window.refreshIcons(document.querySelector('.notifications')))
}
},
/**
* @return {number}
*/
get unread(){
if( !this.data ){
return this.unviewed;
}
return this.data.filter(a => a.is_unread === 0 ).length;
},
/**
*
*/
close(){
this.start = false;
}
}
}

View File

@@ -0,0 +1,29 @@
/**
* @typedef {Object} ConversationResponseItem
*
* @see app/Http/DynamicLoadController.php
*
* @property {string} username
* @property {object} recipients
* @property {boolean} is_starred
* @property {boolean} is_unread
* @property {boolean} can_edit
* @property {boolean} can_reply
* @property {boolean} can_invite
* @property {boolean} can_upload_attachment
* @property {boolean} view_url
* @property {number} conversation_id
* @property {string} title
* @property {number} user_id
* @property {number} start_date
* @property {boolean} open_invite
* @property {boolean} conversation_open
* @property {number} reply_count
* @property {number} recipient_count
* @property {number} first_message_id
* @property {number} last_message_date
* @property {number} last_message_id
* @property {number} last_message_user_id
* @property {Object} Starter
*/
export {}