mirror of
https://github.com/ergochat/ergo.git
synced 2026-04-26 10:38:23 +02:00
add support for draft/chathistory-end tag (#2379)
This commit is contained in:
parent
10da32292f
commit
9556e5c025
@ -63,8 +63,9 @@ const (
|
||||
// BOT mode: https://ircv3.net/specs/extensions/bot-mode
|
||||
BotTagName = "bot"
|
||||
// https://ircv3.net/specs/extensions/chathistory
|
||||
ChathistoryTargetsBatchType = "draft/chathistory-targets"
|
||||
ExtendedISupportBatchType = "draft/isupport"
|
||||
ChathistoryTargetsBatchType = "draft/chathistory-targets"
|
||||
ExtendedISupportBatchType = "draft/isupport"
|
||||
ChathistoryEndOfPaginationTag = "draft/chathistory-end"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@ -979,7 +979,7 @@ func (channel *Channel) autoReplayHistory(client *Client, rb *ResponseBuffer, sk
|
||||
}
|
||||
}
|
||||
if 0 < numItems {
|
||||
channel.replayHistoryItems(rb, items, false)
|
||||
channel.replayHistoryItems(rb, items, false, false)
|
||||
rb.Flush(true)
|
||||
}
|
||||
}
|
||||
@ -1069,7 +1069,7 @@ func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer)
|
||||
client.server.logger.Debug("channels", fmt.Sprintf("%s left channel %s", details.nick, chname))
|
||||
}
|
||||
|
||||
func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.Item, chathistoryCommand bool) {
|
||||
func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.Item, chathistoryCommand, endOfPagination bool) {
|
||||
// send an empty batch if necessary, as per the CHATHISTORY spec
|
||||
chname := channel.Name()
|
||||
client := rb.target
|
||||
@ -1089,7 +1089,11 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||
}
|
||||
}
|
||||
|
||||
batchID := rb.StartNestedBatch("chathistory", chname)
|
||||
var batchTags map[string]string
|
||||
if chathistoryCommand && endOfPagination {
|
||||
batchTags = endOfPaginationTag
|
||||
}
|
||||
batchID := rb.StartNestedBatch(batchTags, "chathistory", chname)
|
||||
defer rb.EndNestedBatch(batchID)
|
||||
|
||||
for _, item := range items {
|
||||
|
||||
@ -939,14 +939,18 @@ func (session *Session) Ping() {
|
||||
session.Send(nil, "", "PING", session.client.Nick())
|
||||
}
|
||||
|
||||
func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.Item, target string, chathistoryCommand bool) {
|
||||
func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.Item, target string, chathistoryCommand, endOfPagination bool) {
|
||||
var batchID string
|
||||
details := client.Details()
|
||||
nick := details.nick
|
||||
if target == "" {
|
||||
target = nick
|
||||
}
|
||||
batchID = rb.StartNestedBatch("chathistory", target)
|
||||
var batchTags map[string]string
|
||||
if chathistoryCommand && endOfPagination {
|
||||
batchTags = endOfPaginationTag
|
||||
}
|
||||
batchID = rb.StartNestedBatch(batchTags, "chathistory", target)
|
||||
|
||||
isSelfMessage := func(item *history.Item) bool {
|
||||
// XXX: Params[0] is the message target. if the source of this message is an in-memory
|
||||
|
||||
@ -38,6 +38,12 @@ import (
|
||||
"github.com/ergochat/ergo/irc/webpush"
|
||||
)
|
||||
|
||||
var (
|
||||
endOfPaginationTag = map[string]string{
|
||||
caps.ChathistoryEndOfPaginationTag: "",
|
||||
}
|
||||
)
|
||||
|
||||
// helper function to parse ACC callbacks, e.g., mailto:person@example.com, tel:16505551234
|
||||
func parseCallback(spec string, config *Config) (callbackNamespace string, callbackValue string, err error) {
|
||||
// XXX if we don't require verification, ignore any callback that was passed here
|
||||
@ -702,6 +708,7 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||
var err error
|
||||
var disabled, listTargets bool
|
||||
var targets []history.TargetListing
|
||||
var endOfPagination bool
|
||||
defer func() {
|
||||
// errors are sent either without a batch, or in a draft/labeled-response batch as usual
|
||||
if disabled {
|
||||
@ -715,7 +722,11 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||
} else {
|
||||
// successful responses are sent as a chathistory or history batch
|
||||
if listTargets {
|
||||
batchID := rb.StartNestedBatch(caps.ChathistoryTargetsBatchType)
|
||||
var batchTags map[string]string
|
||||
if endOfPagination {
|
||||
batchTags = endOfPaginationTag
|
||||
}
|
||||
batchID := rb.StartNestedBatch(batchTags, caps.ChathistoryTargetsBatchType)
|
||||
defer rb.EndNestedBatch(batchID)
|
||||
for _, target := range targets {
|
||||
name := server.UnfoldName(target.CfName)
|
||||
@ -723,9 +734,9 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||
target.Time.Format(utils.IRCv3TimestampFormat))
|
||||
}
|
||||
} else if channel != nil {
|
||||
channel.replayHistoryItems(rb, items, true)
|
||||
channel.replayHistoryItems(rb, items, true, endOfPagination)
|
||||
} else {
|
||||
client.replayPrivmsgHistory(rb, items, target, true)
|
||||
client.replayPrivmsgHistory(rb, items, target, true, endOfPagination)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@ -850,6 +861,12 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||
return
|
||||
}
|
||||
targets, err = client.listTargets(start.Time, end.Time, limit)
|
||||
// adding the end-of-pagination tag is best effort; it's OK if we omit it
|
||||
// in the edge case where we're at the end of the window but we coincidentally
|
||||
// filled the whole limit (the client will just incur an additional roundtrip
|
||||
// to page one more time). in contrast, a false positive would be problematic
|
||||
// because the client would stop paging.
|
||||
endOfPagination = (err == nil) && len(targets) < limit
|
||||
} else {
|
||||
channel, sequence, err = server.GetHistorySequence(nil, client, target)
|
||||
if err != nil || sequence == nil {
|
||||
@ -860,6 +877,7 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||
} else {
|
||||
items, err = sequence.Between(start, end, limit)
|
||||
}
|
||||
endOfPagination = (err == nil) && len(items) < limit
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -1246,9 +1264,9 @@ func historyHandler(server *Server, client *Client, msg ircmsg.Message, rb *Resp
|
||||
|
||||
if len(items) != 0 {
|
||||
if channel != nil {
|
||||
channel.replayHistoryItems(rb, items, true)
|
||||
channel.replayHistoryItems(rb, items, true, false)
|
||||
} else {
|
||||
client.replayPrivmsgHistory(rb, items, "", true)
|
||||
client.replayPrivmsgHistory(rb, items, "", true, false)
|
||||
}
|
||||
}
|
||||
return false
|
||||
@ -3285,7 +3303,7 @@ func metadataRegisteredHandler(client *Client, config *Config, subcommand string
|
||||
return
|
||||
}
|
||||
|
||||
batchId := rb.StartNestedBatch("metadata", target)
|
||||
batchId := rb.StartNestedBatch(nil, "metadata", target)
|
||||
defer rb.EndNestedBatch(batchId)
|
||||
|
||||
for _, key := range params[2:] {
|
||||
@ -3429,7 +3447,7 @@ func metadataSubsHandler(client *Client, subcommand string, params []string, rb
|
||||
|
||||
subs := rb.session.MetadataSubscriptions()
|
||||
|
||||
batchID := rb.StartNestedBatch("metadata-subs")
|
||||
batchID := rb.StartNestedBatch(nil, "metadata-subs")
|
||||
defer rb.EndNestedBatch(batchID)
|
||||
|
||||
chunked := utils.ChunkifyParams(maps.Keys(subs), lineLength)
|
||||
|
||||
@ -67,7 +67,7 @@ func broadcastMetadataUpdate(server *Server, sessions iter.Seq[*Session], origin
|
||||
}
|
||||
|
||||
func syncClientMetadata(server *Server, rb *ResponseBuffer, target *Client) {
|
||||
batchId := rb.StartNestedBatch("metadata", target.Nick())
|
||||
batchId := rb.StartNestedBatch(nil, "metadata", target.Nick())
|
||||
defer rb.EndNestedBatch(batchId)
|
||||
|
||||
subs := rb.session.MetadataSubscriptions()
|
||||
@ -81,7 +81,7 @@ func syncClientMetadata(server *Server, rb *ResponseBuffer, target *Client) {
|
||||
}
|
||||
|
||||
func syncChannelMetadata(server *Server, rb *ResponseBuffer, channel *Channel) {
|
||||
batchId := rb.StartNestedBatch("metadata", channel.Name())
|
||||
batchId := rb.StartNestedBatch(nil, "metadata", channel.Name())
|
||||
defer rb.EndNestedBatch(batchId)
|
||||
|
||||
subs := rb.session.MetadataSubscriptions()
|
||||
@ -107,7 +107,7 @@ func syncChannelMetadata(server *Server, rb *ResponseBuffer, channel *Channel) {
|
||||
}
|
||||
|
||||
func playMetadataList(rb *ResponseBuffer, nick, target string, values map[string]string) {
|
||||
batchId := rb.StartNestedBatch("metadata", target)
|
||||
batchId := rb.StartNestedBatch(nil, "metadata", target)
|
||||
defer rb.EndNestedBatch(batchId)
|
||||
|
||||
for key, val := range values {
|
||||
@ -117,7 +117,7 @@ func playMetadataList(rb *ResponseBuffer, nick, target string, values map[string
|
||||
}
|
||||
|
||||
func playMetadataVerbBatch(rb *ResponseBuffer, target string, values map[string]string) {
|
||||
batchId := rb.StartNestedBatch("metadata", target)
|
||||
batchId := rb.StartNestedBatch(nil, "metadata", target)
|
||||
defer rb.EndNestedBatch(batchId)
|
||||
|
||||
for key, val := range values {
|
||||
|
||||
@ -192,7 +192,7 @@ func (rb *ResponseBuffer) sendBatchEnd(blocking bool) {
|
||||
|
||||
// Starts a nested batch (see the ResponseBuffer struct definition for a description of
|
||||
// how this works)
|
||||
func (rb *ResponseBuffer) StartNestedBatch(batchType string, params ...string) (batchID string) {
|
||||
func (rb *ResponseBuffer) StartNestedBatch(tags map[string]string, batchType string, params ...string) (batchID string) {
|
||||
if !rb.session.capabilities.Has(caps.Batch) {
|
||||
return
|
||||
}
|
||||
@ -201,7 +201,7 @@ func (rb *ResponseBuffer) StartNestedBatch(batchType string, params ...string) (
|
||||
msgParams[0] = "+" + batchID
|
||||
msgParams[1] = batchType
|
||||
copy(msgParams[2:], params)
|
||||
rb.AddMessage(ircmsg.MakeMessage(nil, rb.target.server.name, "BATCH", msgParams...))
|
||||
rb.AddMessage(ircmsg.MakeMessage(tags, rb.target.server.name, "BATCH", msgParams...))
|
||||
rb.nestedBatches = append(rb.nestedBatches, batchID)
|
||||
return
|
||||
}
|
||||
|
||||
@ -535,7 +535,7 @@ func (server *Server) RplISupport(client *Client, rb *ResponseBuffer) {
|
||||
|
||||
func (server *Server) sendRplISupportLines(client *Client, rb *ResponseBuffer, lines [][]string) {
|
||||
if rb.session.capabilities.Has(caps.ExtendedISupport) {
|
||||
batchID := rb.StartNestedBatch(caps.ExtendedISupportBatchType)
|
||||
batchID := rb.StartNestedBatch(nil, caps.ExtendedISupportBatchType)
|
||||
defer rb.EndNestedBatch(batchID)
|
||||
}
|
||||
finalText := "are supported by this server"
|
||||
|
||||
@ -203,7 +203,7 @@ func zncPlayPrivmsgsFrom(client *Client, rb *ResponseBuffer, target string, star
|
||||
zncMax := client.server.Config().History.ZNCMax
|
||||
items, err := sequence.Between(history.Selector{Time: start}, history.Selector{Time: end}, zncMax)
|
||||
if err == nil && len(items) != 0 {
|
||||
client.replayPrivmsgHistory(rb, items, target, false)
|
||||
client.replayPrivmsgHistory(rb, items, target, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ func zncPlayPrivmsgsFromAll(client *Client, rb *ResponseBuffer, start, end time.
|
||||
zncMax := client.server.Config().History.ZNCMax
|
||||
items, err := client.privmsgsBetween(start, end, maxDMTargetsForAutoplay, zncMax)
|
||||
if err == nil && len(items) != 0 {
|
||||
client.replayPrivmsgHistory(rb, items, "", false)
|
||||
client.replayPrivmsgHistory(rb, items, "", false, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
irctest
2
irctest
@ -1 +1 @@
|
||||
Subproject commit 17fac53c5cdfe78caecb601399512574f242cc85
|
||||
Subproject commit c85b574765d67a0270d9c7b35f37ab57e7f95774
|
||||
Loading…
x
Reference in New Issue
Block a user