mirror of
https://github.com/jech/galene.git
synced 2024-11-25 01:55:57 +01:00
Implement selective clearchat.
This commit is contained in:
parent
eb72069c9b
commit
123d51e011
4 changed files with 129 additions and 15 deletions
|
@ -799,10 +799,42 @@ func (g *Group) WallOps(message string) {
|
|||
|
||||
const maxChatHistory = 50
|
||||
|
||||
func (g *Group) ClearChatHistory() {
|
||||
// deleteFunc is just like slices.DeleteFunc.
|
||||
// Remove this once we require Go 1.21.
|
||||
func deleteFunc[S ~[]E, E any](s S, f func(E) bool) S {
|
||||
i := 0
|
||||
for i = range s {
|
||||
if f(s[i]) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i >= len(s) {
|
||||
return s
|
||||
}
|
||||
|
||||
for j := i + 1; j < len(s); j++ {
|
||||
if v := s[j]; !f(v) {
|
||||
s[i] = v
|
||||
i++
|
||||
}
|
||||
}
|
||||
var zero E
|
||||
for j := i; j < len(s); j++ {
|
||||
s[j] = zero
|
||||
}
|
||||
return s[:i]
|
||||
}
|
||||
|
||||
func (g *Group) ClearChatHistory(id string, userId string) {
|
||||
g.mu.Lock()
|
||||
defer g.mu.Unlock()
|
||||
g.history = nil
|
||||
if id == "" && userId == "" {
|
||||
g.history = nil
|
||||
return
|
||||
}
|
||||
g.history = deleteFunc(g.history, func(e ChatHistoryEntry) bool {
|
||||
return e.Source == userId && (id == "" || e.Id == id)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *Group) AddToChatHistory(id, source string, user *string, time time.Time, kind string, value interface{}) {
|
||||
|
|
|
@ -4,9 +4,9 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func TestGroup(t *testing.T) {
|
||||
|
@ -54,7 +54,10 @@ func TestChatHistory(t *testing.T) {
|
|||
}
|
||||
user := "user"
|
||||
for i := 0; i < 2*maxChatHistory; i++ {
|
||||
g.AddToChatHistory("id", "source", &user, time.Now(), "",
|
||||
g.AddToChatHistory(
|
||||
fmt.Sprintf("id-%v", i),
|
||||
fmt.Sprintf("source-%v", i%4),
|
||||
&user, time.Now(), "",
|
||||
fmt.Sprintf("%v", i),
|
||||
)
|
||||
}
|
||||
|
@ -63,10 +66,33 @@ func TestChatHistory(t *testing.T) {
|
|||
t.Errorf("Expected %v, got %v", maxChatHistory, len(g.history))
|
||||
}
|
||||
for i, s := range h {
|
||||
e := fmt.Sprintf("%v", i+maxChatHistory)
|
||||
if s.Value.(string) != e {
|
||||
t.Errorf("Expected %v, got %v", e, s)
|
||||
j := i + maxChatHistory
|
||||
if s.Id != fmt.Sprintf("id-%v", j) {
|
||||
t.Errorf("Expected %v, got %v", j, s.Id)
|
||||
}
|
||||
if s.Source != fmt.Sprintf("source-%v", j%4) {
|
||||
t.Errorf("Expected %v, got %v", j%4, s.Id)
|
||||
}
|
||||
if s.Value.(string) != fmt.Sprintf("%v", j) {
|
||||
t.Errorf("Expected %v, got %v", j, s.Value)
|
||||
}
|
||||
}
|
||||
|
||||
l := len(h)
|
||||
j := maxChatHistory + 4
|
||||
g.ClearChatHistory(
|
||||
fmt.Sprintf("id-%v", j), fmt.Sprintf("source-%v", j%4),
|
||||
)
|
||||
if lh := len(g.GetChatHistory()); lh != l-1 {
|
||||
t.Errorf("Expected %v, got %v", l-1, lh)
|
||||
}
|
||||
g.ClearChatHistory("", fmt.Sprintf("source-%v", j%4))
|
||||
if lh := len(g.GetChatHistory()); lh != l*3/4 {
|
||||
t.Errorf("Expected %v, got %v", l*3/4, lh)
|
||||
}
|
||||
g.ClearChatHistory("", "");
|
||||
if lh := len(g.GetChatHistory()); lh != 0 {
|
||||
t.Errorf("Expected 0, got %v", lh)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1636,10 +1636,27 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
|||
if !member("op", c.permissions) {
|
||||
return c.error(group.UserError("not authorised"))
|
||||
}
|
||||
g.ClearChatHistory()
|
||||
var id, userId string
|
||||
if m.Value != nil {
|
||||
value, ok := m.Value.(map[string]any)
|
||||
if !ok {
|
||||
return c.error(group.UserError(
|
||||
"bad value in clearchat",
|
||||
))
|
||||
}
|
||||
id, _ = value["id"].(string)
|
||||
userId, _ = value["userId"].(string)
|
||||
if userId == "" && id != "" {
|
||||
return c.error(group.UserError(
|
||||
"bad value in clearchat",
|
||||
))
|
||||
}
|
||||
}
|
||||
g.ClearChatHistory(id, userId)
|
||||
m := clientMessage{
|
||||
Type: "usermessage",
|
||||
Kind: "clearchat",
|
||||
Value: m.Value,
|
||||
Privileged: true,
|
||||
}
|
||||
err := broadcast(g.GetClients(nil), m)
|
||||
|
|
|
@ -2781,13 +2781,16 @@ function gotUserMessage(id, dest, username, time, privileged, kind, error, messa
|
|||
let by = username ? ' by ' + username : '';
|
||||
displayWarning(`You have been muted${by}`);
|
||||
break;
|
||||
case 'clearchat':
|
||||
case 'clearchat': {
|
||||
if(!privileged) {
|
||||
console.error(`Got unprivileged message of kind ${kind}`);
|
||||
return;
|
||||
}
|
||||
clearChat();
|
||||
let id = message && message.id;
|
||||
let userId = message && message.userId;
|
||||
clearChat(id, userId);
|
||||
break;
|
||||
}
|
||||
case 'token':
|
||||
if(!privileged) {
|
||||
console.error(`Got unprivileged message of kind ${kind}`);
|
||||
|
@ -3071,17 +3074,31 @@ function chatMessageMenu(elt) {
|
|||
serverConnection.permissions.indexOf('op') >= 0))
|
||||
return;
|
||||
|
||||
let messageId = elt.dataset.id;
|
||||
let peerId = elt.dataset.peerId;
|
||||
if(!peerId)
|
||||
return;
|
||||
let username = elt.dataset.username;
|
||||
let u = username ? ' ' + username : '';
|
||||
let u = username || 'user';
|
||||
|
||||
let items = [];
|
||||
items.push({label: 'Identify user' + u, onClick: () => {
|
||||
if(messageId)
|
||||
items.push({label: 'Delete message', onClick: () => {
|
||||
serverConnection.groupAction('clearchat', {
|
||||
id: messageId,
|
||||
userId: peerId,
|
||||
});
|
||||
}});
|
||||
items.push({label: `Delete all from ${u}`,
|
||||
onClick: () => {
|
||||
serverConnection.groupAction('clearchat', {
|
||||
userId: peerId,
|
||||
});
|
||||
}});
|
||||
items.push({label: `Identify ${u}`, onClick: () => {
|
||||
serverConnection.userAction('identify', peerId);
|
||||
}});
|
||||
items.push({label: 'Kick out user' + u, onClick: () => {
|
||||
items.push({label: `Kick out ${u}`, onClick: () => {
|
||||
serverConnection.userAction('kick', peerId);
|
||||
}});
|
||||
|
||||
|
@ -3098,9 +3115,31 @@ function localMessage(message) {
|
|||
return addToChatbox(null, null, null, null, new Date(), false, false, '', message);
|
||||
}
|
||||
|
||||
function clearChat() {
|
||||
/**
|
||||
* @param {string} [id]
|
||||
* @param {string} [userId]
|
||||
*/
|
||||
function clearChat(id, userId) {
|
||||
lastMessage = {};
|
||||
document.getElementById('box').textContent = '';
|
||||
|
||||
let box = document.getElementById('box');
|
||||
if(!id && !userId) {
|
||||
box.textContent = '';
|
||||
return;
|
||||
}
|
||||
|
||||
let elts = box.children;
|
||||
for(let i = 0; i < elts.length; i++) {
|
||||
let row = elts.item(i);
|
||||
if(!(row instanceof HTMLDivElement))
|
||||
continue;
|
||||
let div = row.firstChild;
|
||||
console.log(div);
|
||||
if(!(div instanceof HTMLDivElement))
|
||||
continue;
|
||||
if((!id || div.dataset.id === id) && div.dataset.peerId === userId)
|
||||
box.removeChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue