Task lists WIP:

* pubsub manager
* some refactoring
* various fixes
This commit is contained in:
John Livingston
2024-05-03 19:28:26 +02:00
parent e8e8af855d
commit df788473cd
7 changed files with 294 additions and 142 deletions

View File

@ -1 +1,2 @@
export const XMLNS_TASKLIST = 'https://livingston.frama.io/peertube-plugin-livechat/protocol/tasklist'
export const XMLNS_TASKLIST = 'urn:peertube-plugin-livechat:tasklist'
export const XMLNS_TASK = 'urn:peertube-plugin-livechat:task'

View File

@ -8,6 +8,8 @@ import './muc-task-list-view.js' // FIXME: here or in another file?
import './muc-task-lists-view.js' // FIXME: here or in another file?
import './modals/muc-task-lists.js' // FIXME: here or in another file?
// TODO: add a client disco feature (using api.listen.on('addClientFeatures' ...)).
converse.plugins.add('livechat-converse-tasks', {
dependencies: ['converse-muc', 'converse-disco'], // TODO: add converse-pubsub

View File

@ -2,7 +2,6 @@ import { Collection } from '@converse/skeletor/src/collection.js'
import { ChatRoomTaskList } from './task-list'
import { XMLNS_TASKLIST } from './constants'
import { initStorage } from '@converse/headless/utils/storage.js'
import { getUniqueId } from '@converse/headless/utils/core.js'
import { converse, api } from '@converse/headless/core'
const { $build } = converse.env
@ -24,8 +23,6 @@ class ChatRoomTaskLists extends Collection {
initStorage(this, id, 'session')
this.on('change:name', () => this.sort())
this.fetchTasksLists().catch(console.error)
}
comparator (tasklist1, tasklist2) {
@ -35,50 +32,6 @@ class ChatRoomTaskLists extends Collection {
return name1 < name2 ? -1 : name1 > name2 ? 1 : 0
}
create (attrs, options) {
if (attrs instanceof ChatRoomTaskList) {
return super.create(attrs, options)
}
attrs.id ??= getUniqueId()
return super.create(attrs, options)
}
/**
* Requires Task lists from the server.
*/
async fetchTasksLists () {
// TODO: remove these test lines, and subscribe to pubsub.
const taskListsData = [
{
id: 'task-list-1',
name: 'Task List 1'
},
{
id: 'task-list-2',
name: 'Task List 2'
}
]
for (const item of taskListsData) {
let id = item.id
const tasklist = id ? this.get(id) : undefined
if (tasklist) {
tasklist.save({
name: item.name
})
return
}
id ??= getUniqueId()
this.create({
id,
name: item.name
})
}
}
async createTaskList (data) {
const name = data?.name
if (!name) { throw new Error('Missing name') }

View File

@ -1,7 +1,6 @@
import { Collection } from '@converse/skeletor/src/collection.js'
import { ChatRoomTask } from './task'
import { initStorage } from '@converse/headless/utils/storage.js'
import { getUniqueId } from '@converse/headless/utils/core.js'
/**
* A list of {@link _converse.ChatRoomTask} instances, representing all tasks associated to a MUC.
@ -22,71 +21,6 @@ class ChatRoomTasks extends Collection {
initStorage(this, id, 'session')
this.on('change:order', () => this.sort())
this.fetchTasks().catch(console.error)
}
create (attrs, options) {
if (attrs instanceof ChatRoomTask) {
return super.create(attrs, options)
}
attrs.id ??= getUniqueId()
return super.create(attrs, options)
}
/**
* Requires Task lists from the server.
*/
async fetchTasks () {
// TODO: remove these test lines, and subscribe to pubsub.
const tasksData = [
{
id: 'task-1',
name: 'Task 1.1',
list: 'task-list-1',
order: 1,
done: false
},
{
id: 'task-2',
name: 'Task 1.2',
list: 'task-list-1',
order: 2,
done: true
},
{
id: 'task-3',
name: 'Task 2.1',
list: 'task-list-2',
order: 1,
done: false
}
]
for (const item of tasksData) {
let id = item.id
const task = id ? this.get(id) : undefined
if (task) {
task.save({
name: item.name,
list: item.list,
order: item.order,
done: item.done
})
return
}
id ??= getUniqueId()
this.create({
id,
name: item.name,
list: item.list,
order: item.order,
done: item.done
})
}
}
}

View File

@ -1,6 +1,7 @@
import { XMLNS_TASKLIST, XMLNS_TASK } from './constants.js'
import { PubSubManager } from '../../shared/lib/pubsub-manager.js'
import { converse, _converse, api } from '../../../src/headless/core.js'
import { __ } from 'i18n'
const { Strophe, $iq } = converse.env
export function getHeadingButtons (view, buttons) {
const muc = view.model
@ -13,6 +14,9 @@ export function getHeadingButtons (view, buttons) {
return buttons
}
// TODO: use disco to discover the feature.
// (if the chat is remote, the server could use a livechat version that does not support this feature)
// Adding a "Open task list" button.
buttons.unshift({
// eslint-disable-next-line no-undef
@ -32,7 +36,7 @@ export function getHeadingButtons (view, buttons) {
}
function _initChatRoomTaskLists (mucModel) {
if (mucModel.tasklists) {
if (mucModel.taskManager) {
// already initiliazed
return
}
@ -40,35 +44,41 @@ function _initChatRoomTaskLists (mucModel) {
mucModel.tasklists = new _converse.ChatRoomTaskLists(undefined, { chatroom: mucModel })
mucModel.tasks = new _converse.ChatRoomTasks(undefined, { chatroom: mucModel })
// Requesting all items.
const stanza = $iq({
type: 'get',
from: _converse.bare_jid,
to: mucModel.get('jid')
}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
.c('items', { node: 'livechat-tasks' })
api.sendIQ(stanza).then(
(iq) => {
console.debug('task lists: ', iq)
},
(iq) => {
if (iq === null || !iq?.querySelector) {
console.error('Failed to retrieve tasks', iq)
return
mucModel.taskManager = new PubSubManager(
mucModel.get('jid'),
'livechat-tasks', // the node name
{
tasklist: {
itemTag: 'tasklist',
xmlns: XMLNS_TASKLIST,
collection: mucModel.tasklists,
fields: {
name: String
}
},
task: {
itemTag: 'task',
xmlns: XMLNS_TASK,
collection: mucModel.tasks,
fields: {
name: String
},
attributes: {
done: Boolean,
list: String,
order: Number
}
}
if (!iq.querySelector('error[type="cancel"] item-not-found')) {
console.error('Failed to retrieve tasks:', iq)
return
}
// This is totally normal when you open an empty task list.
console.log('Not livechat-tasks node for now')
}
)
mucModel.taskManager.start().catch(err => console.log(err))
}
function _destroyChatRoomTaskLists (mucModel) {
if (!mucModel.tasklists) { return }
if (!mucModel.taskManager) { return }
mucModel.taskManager.stop().catch(err => console.log(err))
mucModel.taskManager = undefined
// mucModel.tasklists.unload() FIXME: add a method to unregister from the pubsub, and empty the tasklist.
mucModel.tasklists = undefined