Discussions
https://forum.xwiki.org/t/brainstorming-about-xwiki-discussions/
https://jira.xwiki.org/browse/XWIKI-15966
https://jira.xwiki.org/browse/XWIKI-8088
https://jira.xwiki.org/browse/XWIKI-9104
https://design.xwiki.org/xwiki/bin/view/Proposal/UserMessageNotifications#HInbox
https://extensions.xwiki.org/xwiki/bin/view/Extension/XMPP%20Chat%20Application
https://extensions.xwiki.org/xwiki/bin/view/Extension/ChatApplication
https://markmail.org/message/pw6wtx2lkn72rupv
https://markmail.org/message/vwtfgyf4yyvne4g2
Description
Introduction
This is the design of the extension of XWiki to provide new mechanisms to promote discussions between users inside of XWiki (i.e., without having to rely on third-party such as emails, chats, or forums).
It is worth noting that while participating in discussions from XWiki is the main goal of the extension, a secondary goal is to promote discussions to be possible with third parties using dedicated bridges. The first known use case for this is the interconnection of XWiki discussions with the fediverse, allowing discussions to take place both on XWiki and on other servers supporting the
(e.g., Mastodon).A discussion takes the form of a list of messages sorted by publication time, and centered on a given topic. The discussion can be public, or limited to a set of users and groups.
A discussion can be linked to an entity, for instance, an XWIki page or an XWiki event. The goal is to allow discussions to be centralized in the discussion application but to allow discussions attached to a given entity type to be contextually displayed. For instance, a discussion started from an event triggered by the creation of a new version of a page could be displayed in a tab when consulting the changes of this version of the page.
Table of content
- Introduction
- Table of content
- Architecture Overview
- Domain Overview
- Illustrating use cases
- Missing features
- Architecture
- Detailed domain
- xwiki-platform-discussion-api
- Create
- Read
- List<DiscussionContext> getDiscussionContexts(int offset, int limit)
- int countDiscussionContexts()
- Optional<DiscussionContext> getDiscussionContext(String reference)
- List<Discussion> getDiscussions(List<DiscussionContext> discussionContexts, int offset, int limit)
- int countDiscussions(DiscussionContext discussionContext)
- Optional<Discussion> getDiscussion(String discussionReference)
- List<Messages> getMessages(Discussion discussion, int offset, int limit)
- List<Messages> getRootMessages(Discussuion discussion, int offset, int limit)
- List<Message> getMessage(Message message, int offset, int limit)
- int countMessages(Discussion discussion)
- int countRootMessages(Discussion discussion)
- int countMessages(Message message)
- Optional<Message> getMessage(String messageReference)
- Date getLastUpdate(Discussion discussion)
- Update
- void updateDiscussionContext(String reference, String name, String description)
- void updateDiscussion(String reference, String title, String description)
- void linkDiscussionContext(Discussion discussion, DIscussionContext discussionContext)
- void unlinkDiscussionContext(Discussion discussion, DiscussionContext discussionContext)
- void updateMessage(String reference, String context)
- void pinDiscussion(Discussion discussion)
- void unpinDiscussion(Discussion discussion)
- void pinMessage(Message message)
- void unpinMessage(Message message)
- void updateStates(DiscussionContext discussionContext, List<String> states)
- void updateStates(Discussion discussion, List<String> states)
- void updateStates(Message message, List<String> states)
- addAdminGroup(DiscussionContext discussionContext, Group group)
- addAdminUser(DiscussionContext discussionContext, User user)
- removeAdminGroup(DiscussionContext discussionContext, Group group)
- removeAdminUser(DiscussionContext discussionContext, User user)
- addAdminGroup(Discussion discussion, Group group)
- addAdminUser(Discussion discussion, User user)
- removeAdminGroup(Discussion discussion, Group group)
- removeAdminUser(Discussion discussion, User user)
- addReadGroup(Discussion discussion, Group group)
- addReadUser(Discussion discussion, Group group)
- removeReadGroup(Discussion discussion, User user)
- removeReadUser(Discussion discussion, User user)
- addWriteGroup(Discussion discussion, Group group)
- addWriteUser(Discussion discussion, Group group)
- removeWriteGroup(DiscussionContext discussion, User user)
- removeWriteUser(DiscussionContext discussion, User user)
- Delete
- void pinDiscussionContext(String reference)
- void unpinDiscussionContext(String reference)
- void pinDiscussion(String reference)
- void unpinDiscussion(String reference)
- void pinMessage(String reference)
- void unpinMessage(String reference)
- xwiki-platform-discussion-rest
- xwiki-platform-discussion-store-api
- DiscussionContextService
- DiscussionContext create(String entityReferenceType, String entityReference, String name, String description)
- Optional<DiscussionContext> get(String reference)
- List<DiscussionContext> list(String type, int offset, int limit)
- List<DiscussionContext> listByDiscussion(String discussionReference, int offset, int limit)
- void update(String reference, String name, String description)
- void updateAdministrators(String reference, List<User> users, List<Group> groups)
- void setState(String reference, String state)
- void pin(String reference)
- void unpin(String reference)
- void attachDiscussion(String discussionContextReference, String discussionReference)
- void detachDiscussion(String discussionContextReference, String discussionReference)
- void delete(String reference)
- DiscussionService
- Discussion create(String title, String description)
- Optional<Discussion> get(String reference)
- void update(String reference, String title, String description)
- void updateAdministrators(String reference, List<User> users, List<Group> groups)
- void setState(String reference, String state)
- void pin(String reference)
- void unpin(String reference)
- void attachDiscussionContext(String discussionReference, String discussionContextReference)
- void detachDiscussionContext(String discussionReference, String discussionContextReference)
- void delete(String reference)
- MessageService
- DiscussionContextService
- xwiki-platform-discussion-store-default
- xwiki-platform-discussion-ui
- User Interface Specifications
- Tasks
Architecture Overview
- xwiki-platform-discussion-api: Provides the operations to interact with the discussions
- xwiki-platform-discussion-default: Default implementation of the discussions API
- xwiki-platform-discussion-rest: Provides the REST operations to interact with the discussion
- xwiki-platform-discussion-store-api: Provides the operations to interact with the discussion store
- xwiki-platform-discussion-store-default: Default implementation of the store API, where the discussion entities are stored in xpages
- xwiki-platform-discussion-ui: Provides the generic user interfaces of the discussions as well as reusable macros to integrate the discussions contextually in XWiki's interfaces
Domain Overview
This section describes the main concepts manipulated in the context of the discussions
Discussion Context
A discussion context represents a group of discussions sharing a relation to the same entity.
A discussion can be part of several discussion contexts.
Entity Reference
An entity reference stores the reference to an entity in the wiki.
It is composed of the type of the referenced entity, and a serialized reference, expected to be read according to the type referenced entity.
Discussion
A discussion represents a collection of messages sharing a common topic.
A discussion can be part of several discussion contexts.
Message
A message is a textual contribution to a discussion. Messages are usually displayed ordered by their creation dates.
A message can be a reply to another message, forming arborescent discussions.
Illustrating use cases
As this extension is by itself abstract, we propose in this section some application use cases illustrating the use of the extension in some concrete context.
This is also a way to verify that the current design is general enough to fit a reasonable range of application use cases.
Each section starts with a short description of the use case then describes the use of the discussion APIs to realize it.
Comments
Description
Comment are sequences of messages that can answer each other and are attached to a wiki page.
They are displayed at the bottom of the page.
Comments can be posted by anonymous or logged in users that can view the page and are allowed to comment.
Administrators can edit and remove all the messages.
Users can edit and remove their messages.
Realization
Commenting
When a comment is added:
- We check for the author right to verify he/she is allowed to post a message on this page
- We look for a discussion context with entityReferenceType="document", entityeReference="xwiki:XWiki.MyPage".
- If it does not exist
- A discussion context is created with entityReferenceType="document", entityeReference="xwiki:XWiki.MyPage", name="Page name", description="Comments of page Page name", administators=defined by the comments administration configuration.
- A discussion is created and linked to the previously created discussion context, with title="Comments of Page name", description="Comments of Page name", administrators=defined by the comments administration configuration
- The created discussion is returned
- If it does exist:
- We look for the only discussion linked to the discussion context and return it
- The message is created in the returned discussion
Other actions
Editing, removing, pining are straightforward and should be realized by generic actions provided by the reusable UI.
Starting a discussion from a notification
A notification is received, let's say for a new message received from ActivityPub (AP). The data attached to the event contains an AP Page object
In the notifications pane, a button is provided to answer the notification, opening a modal window with a form to add a message.
When the comment is sent:
- Check if a discussion exists with relations to exactly two discussion contexts:
- activitystream:the-event-id
- activitypub:the AP Page ID
- Create the two discussion contexts if they respectively do not exist.
- Create the discussion linked exactly to the two discussion contexts, otherwise returns it.
- Add the message to the discussion
- A new message event is send and listened to by the AP application. The message is send to the fediverse, to the author of the page we replied to.
Consulting the discussion:
Now the discussion could be seen in three places, if the applications listed application made the effort to integrate them:
- The general view of all the discussions the user can see (provided by the discussions application)
- The view of the discussions started from notifications (provided by activity stream)
- The view of the discussions link to the AP Page (provided by AP)
Private messages between two users
User U1 wants to start a discussion with user U2.
U1 goes to the profile page of U2.
A discussion tab is proposed and is currently empty.
U1 type a first message.
- Check if a discussion exists with relations to exactly two discussion contexts (admitting the users are identified by their profile page, this will change with the new actors API):
- document:xwiki:XWiki.U1
- document:xwiki:XWiki.U2
- Creates the two discussion contexts and the discussion if they do not exist.
- Add the message to the discussion
- U2 is notified of the new message through the notifications mechanism.
- The discussion is now displayed in the discussion lists of U1 and U2 in their profiles.
Forum
In the context of a forum application, different discussion spaces called forums can be created by administrators.
Creating a forum creates a corresponding discussion contexts, the type of the discussion context entities can either be a new "forum" type, if we want to make the forum independent of XWiki pages for the storage, or otherwise directly of type "page", in a dedicated space.
A discussion, in the case, is created and linked to a single discussion context.
Messages are created as usual.
Missing features
This section lists missing features that must be integrated to the design
- Anonymous users can post messages
- Captcha integration
Architecture
Detailed domain
DiscussionContext
A group of discussions share a common context.
- reference: String
- entityReferenceType: String
- entityReference: String
- name: String
- description: String
- creation date: Date
- update date: Date
- states: List<String>
- pined: boolean
Discussion
A group of messages
- reference: String
- title: String
- description: String
- creation date: Date
- update date: Date
- states: List<String>
- pined: boolean
- lastActivity: Date (derived) last activity of the discussion, the most recent date of the discussion's update date and the discussion's messages update dates
Message
A message on a discussion
- reference: String
- content: String
- Discussion id: String
- author: UserReference
- creation date: date
- update date: date
- states: List<String>
- replyTo: Message
- pined: boolean
xwiki-platform-discussion-api
Create
DiscussionContext createDiscussionContext(String name, String description, String referenceType, String entityReference)
Create and save a discussion context.
Two discussion can have the same name.
Throw an error if the the actor does not have the right to create a discussion context.
Set the creation date of the discussion context.
Discussion createDiscussion(String title, List<DiscussionContext> discussionContexts)
Create and save a discussion, and link it to the provided list of discussion contexts.
Two discussions can have the same title.
Throw an error if the actor does not have the right to create a discussion.
Set the creation date of the discussion.
Message createMessage(String content, Discussion discussion)
Create and save a message in a discussion.
Thrown an error if the actor does not have the right to create a message.
Throw an error if the actor does not have the right to add a message to the discussion.
Set the creation date of the message.
Other operations
- Attach an administrator to a forum
- Attach an administrator to a discussion
- Other right management operation
Read
List<DiscussionContext> getDiscussionContexts(int offset, int limit)
Returns a paginated list of the discussion contexts.
The pined discussion contexts are returned first.
int countDiscussionContexts()
Returns a count of the discussion contexts.
Optional<DiscussionContext> getDiscussionContext(String reference)
Returns a discussion by its reference.
The optional is empty if:
- the actor does not have the right to access the forum
- no forum is found for the reference
List<Discussion> getDiscussions(List<DiscussionContext> discussionContexts, int offset, int limit)
Returns a paginated list of the discussions linked to the list of discussion contexts passed in parameter.
The pined discussions are returned first.
int countDiscussions(DiscussionContext discussionContext)
Returns the count of the discussions attached to a discussion context.
Optional<Discussion> getDiscussion(String discussionReference)
Returns a discussion by its reference.
The optional is empty if:
- the actor does not have the right to view the discussion
- no discussion is found for the reference
List<Messages> getMessages(Discussion discussion, int offset, int limit)
Returns a paginated list of the messages of a discussion.
Throw an error if the actor is not allowed to view the discussion.
List<Messages> getRootMessages(Discussuion discussion, int offset, int limit)
Returns a paginated list of the root messages of a discussion (i.e., the messages with an empty replyTo field).
Throw an error if the actor is not allowed to view the discussion.
List<Message> getMessage(Message message, int offset, int limit)
Returns a paginated list of the messages that are replies to the message passed in parameter.
Throw an error if the actor is not allowed to view the discussion.
int countMessages(Discussion discussion)
Returns a count of the messages in a discussion.
int countRootMessages(Discussion discussion)
Returns a count of the root messages in a discussion (i.e., the message with an empty replyTo field).
int countMessages(Message message)
Returns a count of the number of replies to the message passed in parameter.
Optional<Message> getMessage(String messageReference)
Returns a message by its reference.
The optional is empty if:
- the actor does not have the right to view the message
- no message is found for the reference
Date getLastUpdate(Discussion discussion)
Returns the date of the last action performed on the discussion, it is the most recent date of:
- the creation of the discussion
- an update of a discussion field
- the creation of a message on the discussion
- the update of a message of the discussion
Update
void updateDiscussionContext(String reference, String name, String description)
Updates the updatable information of a forum:
- its name
- its description
Changes the update date of the discussion context.
Throw an error is the actor is not allowed to update the discussion context.
void updateDiscussion(String reference, String title, String description)
Updates the updatable information of a discussion:
- its title
- its description
Changes the update date of the discussion.
Throw an error if the actor is not allowed to update the discussion.
void linkDiscussionContext(Discussion discussion, DIscussionContext discussionContext)
Links a discussion to a discussion. The relation is bidirectional.
void unlinkDiscussionContext(Discussion discussion, DiscussionContext discussionContext)
Unlinks a discussion and on of its linked discussion context.
void updateMessage(String reference, String context)
Update the updatable information of a message:
- its message
Change the update date of the message.
Throw an error if the actor is not allowed to update the message.
void pinDiscussion(Discussion discussion)
Pin a discussion.
void unpinDiscussion(Discussion discussion)
Unpin a discussion.
void pinMessage(Message message)
Pin a message.
void unpinMessage(Message message)
Unpin a message.
void updateStates(DiscussionContext discussionContext, List<String> states)
The state are an open mechanism to add custom metadatas to a discussion context.
Updates the list of states of the discussion context.
void updateStates(Discussion discussion, List<String> states)
The state are an open mechanism to add custom metadatas to a discussion context.
Updates the list of states of the discussion.
void updateStates(Message message, List<String> states)
The state are an open mechanism to add custom metadatas to a discussion context.
Updates the list of states of the message.
addAdminGroup(DiscussionContext discussionContext, Group group)
Add a group to the list of administrators of the discussion context.
addAdminUser(DiscussionContext discussionContext, User user)
Add a user to the list of administrators of the discussion context.
removeAdminGroup(DiscussionContext discussionContext, Group group)
Remove a group from the list of administators of the discussion context.
removeAdminUser(DiscussionContext discussionContext, User user)
Remove a user from the list of administrators of the discussion context.
addAdminGroup(Discussion discussion, Group group)
Add an group of the list of administrators of the discussion.
addAdminUser(Discussion discussion, User user)
Add a user to the list of administrators of the discussion.
removeAdminGroup(Discussion discussion, Group group)
Remove an group from the list of administrators of the discussion.
removeAdminUser(Discussion discussion, User user)
Remove a user from the list of administrators of the discussion
addReadGroup(Discussion discussion, Group group)
Add a group to the list of readers of the discussion.
addReadUser(Discussion discussion, Group group)
Add a user to the list of readers of the discussion.
removeReadGroup(Discussion discussion, User user)
Remove a group from the list of readers of the discussion.
removeReadUser(Discussion discussion, User user)
Remove a user from the list of readers of the discussion.
addWriteGroup(Discussion discussion, Group group)
Add a group to the list of writers of the discussion.
addWriteUser(Discussion discussion, Group group)
Add a user to the list of writers of the discussion.
removeWriteGroup(DiscussionContext discussion, User user)
Remove a group from the list of writers of the discussion.
removeWriteUser(DiscussionContext discussion, User user)
Remove a user from tthe list of writers of the discussion.
Delete
void deleteDiscussionContext(DiscussionContext forum)
Delete a discussion context.
Throw an error if the actor does not have the right to delete the discussion context.
After deleting the discussion context, checks for orphaned discussions and remove them as well ("garbage collection like").
void deleteDiscussion(Discussion discussion)
Dete a discussion.
Throw an error if the actor does not have the right do delete the discussion
After deleting a discussion, checks for orphaned discussion context are remove the as well ("garbage collection like").
void deleteMessage(Message message)
Delete a message.
Throw an error if the actor does not have the right to delete the message.
void pinDiscussionContext(String reference)
Switch the status of the discussion context to pined.
void unpinDiscussionContext(String reference)
Switch the status of the discussion context to pined.
void pinDiscussion(String reference)
Switch the status of the discussionto pined.
void unpinDiscussion(String reference)
Switch the status of the discussion to pined.
void pinMessage(String reference)
Switch the status of the message to pined.
void unpinMessage(String reference)
Switch the status of the message to pined.
xwiki-platform-discussion-rest
Name | HTTP Method | Path | Path param | Get params | Body Params | Response | Description | Need authentication? |
---|---|---|---|---|---|---|---|---|
createDiscussionContext | POST | /discussionContext |
| The created discussion context object | Creates a discussion context | TBD | ||
deleteDiscussionContext | DELETE | /discussionContext/{discussionContextReference} |
| a success code | Delete a discussion context | |||
createDiscussion | POST | /discussion |
| The created discussion object | Creates a discussion | TBD | ||
delete Discussion | DELETE | /discussion/{discussionReference} |
| a success code | Delete a discussion | |||
createMessage | POST | /message |
| The created message object | Create a message in a discussion | TBD | ||
deleteMessage | DELETE | /message/{messageReference} |
| a success code | Delete a message | |||
updateDiscussionContext | PUSH | /discussionContext |
| The updated discussion context | Update the name and description of a discussion context | TBD | ||
updateDisucssion | PUSH | /discussion |
| The updated discussion | Update the title and description of a discussion | TBD | ||
updateMessage | PUSH | /message |
| The updated message | Update the content of a message | TBD | ||
linkDiscussionAndDiscussionContext | PUSH | /discussionContext/link |
| success/error code only | Link a discussion and a discussion context | TBD | ||
unlinkDiscussionAndDiscussionContext | DELETE | /discussionContext/link |
| success/error code only | Unlink a discussion and a discussion context | TBD | ||
getDiscussionContexts | GET | /discussionContext |
| the paginated list of discussion contexts, optionally filtered by type, and sorted by the sort criteria | Returns a paginated list of discussion contexts | TBD | ||
countDiscussionContext | GET | /discussionContexts/count | same as getDiscussionContexts, except for the pagination and sort | same as getDiscussionContexts but returns the the number of results instead | ||||
getDiscussions | GET | /discussion |
| the paginated list of discussions, optionally filtered by type and/or entity reference, and sorted by the sort criteria | Returns a paginated list of discussions | TBD | ||
countDiscussions | GET | /discussion/count | same as getDiscussions except for the pagination and sort | same as getDiscussions but returns the number of results instead | ||||
getMessages | GET | /discussion/{discussionReference}/messages |
|
| the paginated list of messages of a discussion, sort by by sort criterion | Returns a paginated list of messages | TBD | |
countMessages | GET | /discussion/{discussionReference}/messages/count | same as getMessages | same as getMessages, exception of the pagination and sort | same as getMessages but returns the number of results instead | |||
getDiscussionContext | GET | /discussionContext/{discussionContextReference} |
| the object | returns a single discussion context | TBD | ||
getDiscussion | GET | /discussion/{discussionRefernece} |
| the object | returns a single discussion | TB | ||
getMessage | GET | /message/{messageReference} |
| the object | returns a single message | TBD | ||
pinDiscussion | PUSH | /discussion/{discussionReference}/pin | TODO | TBD | pin a discussion | |||
unpinDiscussion | PUSH | /discussion/{discussionReference}/unpin | TODO | TBD | unpin a discussion | |||
pinMessage | PUSH | /message/{messageReference}/pin | TODO | TBD | pin a message | |||
unpinMessage | PUSH | /message/{messageReference}/unpin | TODO | TBD | unping a message |
xwiki-platform-discussion-store-api
This module provides the low level operation required to realize the actions proposed by xwiki-platform-discussion-api. For instance no rights control are done before performing the operations.
This modules is nonetheless in charge of the data concistency of its entities. It must control and raise errors if an operation would break the concistency of the application by being performed.
The section regroups the operations for each manipulable entity (see the detailed domain).
DiscussionContextService
DiscussionContext create(String entityReferenceType, String entityReference, String name, String description)
Creates and initializes a discussion context.
The list of administrator users is initialized with the current user.
This list of administrator groups is empty.
The creation and update dates are set to now.
The state is empty.
This pined field is set to false.
Optional<DiscussionContext> get(String reference)
Returns a discussion context from its reference.
List<DiscussionContext> list(String type, int offset, int limit)
Returns a list of discussion contexts of a given type.
List<DiscussionContext> listByDiscussion(String discussionReference, int offset, int limit)
Returns the list of discussion contexts linked to the passed discussion reference.
void update(String reference, String name, String description)
Update the name and description of the discussion context.
Update the update date of the object.
void updateAdministrators(String reference, List<User> users, List<Group> groups)
Replace the lists of administrator users and groups with the new lists.
Update the update date of the object.
void setState(String reference, String state)
Replaces the state of the object.
Update the update date of the object.
void pin(String reference)
Pin the object.
Update the update date of the object.
void unpin(String reference)
Unpin the object.
Update the update date of the object.
void attachDiscussion(String discussionContextReference, String discussionReference)
Links a discussion to a discussion context.
Update the update date of the discussions context as well as the discussion.
void detachDiscussion(String discussionContextReference, String discussionReference)
Unlinks a discussion and a discussion context.
Update the update date of the discussion context as well the discussion.
Removes the discussion context if it is now connect to 0 discussions.
Removes the discussion if it is now connect to 0 discussion contexts.
void delete(String reference)
Delete the object.
Checks if some discussions are now without discussion contexts and remove them too.
DiscussionService
Discussion create(String title, String description)
Creates and initializes the discussion.
Set the current user as administrator.
The administator group list is empty.
Set the creation date to now.
Set the update date to now.
The state is empty.
The discussion is not pined.
Optional<Discussion> get(String reference)
Returns the discssion
void update(String reference, String title, String description)
Update the title and description of the object.
Update the update date.
void updateAdministrators(String reference, List<User> users, List<Group> groups)
Replace the lists of administrator users and groups with the new lists.
Update the update date of the object.
void setState(String reference, String state)
Replaces the state of the object.
Update the update date of the object.
void pin(String reference)
Pin the object.
Update the update date of the object.
void unpin(String reference)
Unpin the object.
Update the update date of the object.
void attachDiscussionContext(String discussionReference, String discussionContextReference)
Links a discussion context to a discussion.
Update the update date of the discussion as well as the discussion context.
void detachDiscussionContext(String discussionReference, String discussionContextReference)
Unlinks a discussion and a discussion context.
Update the update date of the discussion context as well the discussion.
Removes the discussion if it is now connect to 0 discussion contexts.
Removes the discussion context if it is now connect to 0 discussions.
void delete(String reference)
Delete the object.
Checks if some discussions context are now without discussions and remove them too.
MessageService
Message create(String content, User author)
Creates and initializes a message with the content and author.
Set the creation and update dates to now.
The state is empty.
The reply to is empty
Message create(String content, User author, String replyToReference)
Creates and initializes a message with the content, author and replyToReference.
Set the creation and update dates to now.
The state is empty.
void update(String reference, String content)
Update the content of the message.
Set the update date to now.
void delete(String reference)
Delete the message.
xwiki-platform-discussion-store-default
Let's take the hypothesis that XWIKI-17174 will be addressed.
Where are discussion context stored?
Discussion Contexts are stored in pages and contains a DiscussionContext XObject.
Each discussion context is stored in its own page, under a common space Discussions.DiscussionContext.XXXX where XXXX is a unique page name composed of the discussion context title + a random short string.
Where are the entity references stored?
The entity references are stored directly inside the discussion context. If several discussion contexts references the same entity, they have duplicated references / reference types.
Where are relations between entity references and discussion context stored?
The discussion contexts contains a list of discussions references.
The discussion contains a list of discussion contexts.
The application is in charge of keeping track of the consistency of there relations.
Where are discussions stored?
Discussions are stored in pages and contains a Discussion object.
Can a single page contains several discussions? NO
Each discussion is stored in its own page, under a common space Discussions.Discussions.XXXX where XXXX is a unique page name composed of the discussion title + a random short string
Where a message stored ?
Messages are stored in the page of their discussion in message XObjects.
If XWIKI-17174 is not addresed, messages will need to be stored in sub-pages of the discussion page.
xwiki-platform-discussion-ui
User Interface Specifications
TODO
- Pin a discussion context
- Should be integrated to the discussion administration
- Administrate a discussion context
- Should take the form of a generic administration could be provided. It will take the form of an object editor for the DiscussionContext instance (+ some business rules validation and specific buttons such as remove or pin?).
- View the discussion context list
- Should take the form of a macro returning the UI for the list of discussion contexts according to some criteria (for a type of entity and/or an entity reference).
- Delete a discussion context
- Programmatically?
- Create a discussion
- Should take the form of a macro that can be integrated where needed.
- Administrate a discussion
- Should take the form of a generic administration for the discussion. It will take the form of an object editor for the Discussion instance (+ some business rules validation and specific buttons such as remove or pin?)
- View the paginated list of discussions AKA DISCUSSION INDEX
- Generic macro to view a paginated list of all the discussions related to a given user
- View the paginated list of discussions by discussion context
- Generic macro to view a paginated list of all the discussion related to a given user and a given discussion context
- View the paginated list of discussions by discussion context type
- Generic macro to view a paginated list of all the discussion related to a given user and a given discussion context type
- Implement a specific use of the discussion listing to define the main page of the discussions, show relevant discussions to the current user (this one might be complex)
- View a discussion
- Generic macro to view a a discussion. It should also be integrated by default and accessible from the discussions lists.
- Pin a discussion
- Should be integrated to the discussion context administration (note: can a discussion be pined in one discussion context and not in another one ?)
- Delete a discussion
- should be integrated to the discussion administration
- Create a message
- should be integrated to the discussion view UI
- Update a message
- should be provided as a reusable macro but also accessible easily from the discussion view UI
- Delete a message
- should be a button integrated to the discussion view UI
- Pin a message
- should be integrated to the discussion administration
Main page
View a discussion
A header presents the title and description of the discussion.
The messages are displayed paginated, the oldest message at the top.
Each message present the avatar of the author and the content of the message, plus the available actions for the message, according to the rights of the current user:
- delete
- edit
- pin
- ...
At the bottom of the page, a form is available if the current user has the right to write to add a new message to the discussion.
Administrate a discussion
The administration of the discussion is opened to the administrators of the discussion.
A form is proposed to update the title and description of the discussion.
A button is also proposed to remove the discussion.
Administrate a discussion rights
A page is available to administrate the discussions rights.
ActivityPub integration
This section discuss more specifically the integration of ActivityPub with the Discussions but should be seen as a tentative to make the discussions bridgeable with external discussion systems.
Sending a message to the fediverse
When creating a discussion, the user pick to select the members of the discussion is extensible and should propose different sources of groups and users.
When the activity pub user source is activated, actors of the fediverse can be added to the list of members of the discussion.
In this case, the messages of the discussion should also be sent to the fediverse, in the form of Notes replying to the most recent message of the discussion by filling the inReplyTo field of the note with the activitypub identifier of the most recent message of the discussion.
Receiving a message from the fediverse
When receiving a inReplyTo field containing the identifier of a message of a discussion, the message should be added to the corresponding discussion unless:
- the actor of the fediverse is not a member of the discussion
Tasks
UC# | Depends on | Title | Complexity | Priority |
---|---|---|---|---|
UC1.1 | extensible user picker | Creating a new discussion | ||
UC1.2 | quick actions, extensible user picker | Creating a discussion from the notifications | ||
UC2 | Listing the discussions | |||
UC3 | Displaying a discussion | |||
UC4 | See the messages of a discussion | |||
UC5 | Reply to a discussion | |||
UC6 | Administrate a discussion | |||
UC7 | Administrate a discussion context | |||
UC8 | Create a discussion context | |||
UC9 | Delete a discussion context | |||
UC10 | Delete a discussion | |||
UC11 | Delete a message | |||
UC13 | Link a discussion context and a discussion | |||
UC14 | Unlink a discussion context and a discussion | |||
UC15 | Send event when dicussions context/discussions/messages are created, updated or deleted | |||
UC16 | Administrate a discussion context rights | |||
UC17 | Administrate a discussion rights | |||
UC18 | Pin a discussion context | |||
UC19 | Pin a discussion | |||
UC20 | Pin a message | |||
UC21 | Archive a discussion context | |||
UC22 | Archive a discussion | |||
UC23 | Archive a message |
UC1 - Creating a new discussion
UC1.1 - Creation a discussion from the notifications
UC2 - Listing the discussions
Definition of the display of the discussions and its integration on the main page.
UC3 - Displaying a discussion
UC4 - Editing an existing message
UC5 - ActivityPub Specific UCs
Sharing a discussion with the