/mybots: Edit Bot summary screen, return-to-menu, clickable @mentions
- Edit Bot now shows the current value of every field (Name/About/ Description/Botpic/Commands) like BotFather, with real botpic status via a new PeerHasAvatar port method. - After editing a field the dialog lands back on a fresh Edit Bot menu (working "Back to bot" / "Bots list" buttons) instead of ending, so a follow-up button press no longer reports the button as expired. - Service-bot messages now render @username as a tappable mention entity.
This commit is contained in:
parent
f474a360d7
commit
5afafc60c4
7 changed files with 215 additions and 10 deletions
|
|
@ -45,6 +45,10 @@ func serviceBotReplyEntities(text string, explicit []domain.MessageEntity) []dom
|
|||
offset, length := utf16Range(text, span.start, span.end)
|
||||
appendEntity(domain.MessageEntity{Type: domain.MessageEntityBotCommand, Offset: offset, Length: length})
|
||||
}
|
||||
for _, span := range serviceBotMentionByteSpans(text) {
|
||||
offset, length := utf16Range(text, span.start, span.end)
|
||||
appendEntity(domain.MessageEntity{Type: domain.MessageEntityMention, Offset: offset, Length: length})
|
||||
}
|
||||
sort.SliceStable(out, func(i, j int) bool {
|
||||
if out[i].Offset != out[j].Offset {
|
||||
return out[i].Offset < out[j].Offset
|
||||
|
|
@ -138,6 +142,42 @@ func serviceBotCommandByteSpans(text string) []serviceBotEntitySpan {
|
|||
return spans
|
||||
}
|
||||
|
||||
// serviceBotMentionByteSpans finds "@username" runs so a service bot's messages
|
||||
// render the mention as a tappable link. A username is 5-32 of [A-Za-z0-9_]; the
|
||||
// "@" must not sit right after a word character (so "you@example" is not a
|
||||
// mention) and the run must not be followed by one.
|
||||
func serviceBotMentionByteSpans(text string) []serviceBotEntitySpan {
|
||||
var spans []serviceBotEntitySpan
|
||||
for i := 0; i < len(text); {
|
||||
r, size := utf8.DecodeRuneInString(text[i:])
|
||||
if r != '@' || !serviceBotCommandStart(text, i) {
|
||||
i += size
|
||||
continue
|
||||
}
|
||||
start := i
|
||||
i += size
|
||||
nameStart := i
|
||||
for i < len(text) {
|
||||
c, csize := utf8.DecodeRuneInString(text[i:])
|
||||
if !serviceBotCommandChar(c) {
|
||||
break
|
||||
}
|
||||
i += csize
|
||||
}
|
||||
nameLen := i - nameStart
|
||||
if nameLen < 5 || nameLen > 32 {
|
||||
continue
|
||||
}
|
||||
if i < len(text) {
|
||||
if next, _ := utf8.DecodeRuneInString(text[i:]); serviceBotCommandChar(next) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
spans = append(spans, serviceBotEntitySpan{start: start, end: i})
|
||||
}
|
||||
return spans
|
||||
}
|
||||
|
||||
func serviceBotCommandStart(text string, byteIndex int) bool {
|
||||
if byteIndex == 0 {
|
||||
return true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue