125 lines
5.8 KiB
Go
125 lines
5.8 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"telesrv/internal/domain"
|
|
"time"
|
|
)
|
|
|
|
func (s *ChannelStore) SetPreHistoryHidden(_ context.Context, userID, channelID int64, enabled bool) (domain.Channel, error) {
|
|
if userID == 0 || channelID == 0 {
|
|
return domain.Channel{}, domain.ErrChannelInvalid
|
|
}
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
channel, err := s.channelForMemberLocked(userID, channelID)
|
|
if err != nil {
|
|
return domain.Channel{}, err
|
|
}
|
|
member := s.members[channelID][userID]
|
|
if member.Role != domain.ChannelRoleCreator {
|
|
return domain.Channel{}, domain.ErrChannelAdminRequired
|
|
}
|
|
prev := channel.PreHistoryHidden
|
|
channel.PreHistoryHidden = enabled
|
|
s.channels[channelID] = channel
|
|
if prev != enabled {
|
|
s.appendChannelAdminLogLocked(domain.ChannelAdminLogEvent{
|
|
ChannelID: channelID,
|
|
UserID: userID,
|
|
Date: int(time.Now().Unix()),
|
|
Type: domain.ChannelAdminLogTogglePreHistoryHidden,
|
|
PrevBool: prev,
|
|
NewBool: enabled,
|
|
})
|
|
}
|
|
return channel, nil
|
|
}
|
|
|
|
func (s *ChannelStore) SetPaidMessagesPrice(_ context.Context, userID, channelID int64, stars int64, broadcastMessagesAllowed bool) (domain.ChannelPaidMessagesPriceResult, error) {
|
|
if userID == 0 || channelID == 0 || stars < 0 {
|
|
return domain.ChannelPaidMessagesPriceResult{}, domain.ErrChannelInvalid
|
|
}
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
channel, err := s.channelForMemberLocked(userID, channelID)
|
|
if err != nil {
|
|
return domain.ChannelPaidMessagesPriceResult{}, err
|
|
}
|
|
member := s.members[channelID][userID]
|
|
if !canChangeChannelInfo(member) {
|
|
return domain.ChannelPaidMessagesPriceResult{}, domain.ErrChannelAdminRequired
|
|
}
|
|
out := domain.ChannelPaidMessagesPriceResult{}
|
|
prevAllowed := channel.BroadcastMessagesAllowed
|
|
prevStars := channel.SendPaidMessagesStars
|
|
prevLinked := channel.LinkedMonoforumID
|
|
channel.SendPaidMessagesStars = stars
|
|
channel.BroadcastMessagesAllowed = channel.Broadcast && broadcastMessagesAllowed
|
|
changed := channel.Broadcast && (prevAllowed != channel.BroadcastMessagesAllowed || prevStars != stars || (channel.BroadcastMessagesAllowed && prevLinked == 0))
|
|
// 开启频道私信时关联 monoforum 虚拟频道(与 postgres 行为一致);复用既有则只同步价格。
|
|
if channel.BroadcastMessagesAllowed {
|
|
if channel.LinkedMonoforumID == 0 {
|
|
monoID := s.nextChannelIDLocked()
|
|
s.channels[monoID] = domain.Channel{
|
|
ID: monoID,
|
|
AccessHash: s.nextAccessHashLocked(),
|
|
CreatorUserID: channel.CreatorUserID,
|
|
Title: channel.Title,
|
|
// Keep monoforum as a megagroup-like saved sublist container. TDesktop hangs when
|
|
// a monoforum peer is projected as both broadcast and megagroup.
|
|
Megagroup: true,
|
|
Monoforum: true,
|
|
LinkedMonoforumID: channelID,
|
|
SendPaidMessagesStars: stars,
|
|
Date: int(time.Now().Unix()),
|
|
}
|
|
channel.LinkedMonoforumID = monoID
|
|
} else if mono, ok := s.channels[channel.LinkedMonoforumID]; ok {
|
|
// 复用既有 monoforum 只同步价格。mono 恒以 megagroup 形态创建、无路径会翻成 broadcast/forum,
|
|
// 故无需再规范化 kind(那是对从未发布的 broadcast+monoforum 实验形态的历史数据修复死代码)。
|
|
// 与 postgres 保持一致。
|
|
mono.SendPaidMessagesStars = stars
|
|
s.channels[channel.LinkedMonoforumID] = mono
|
|
}
|
|
// monoforum 首条(也是唯一)服务消息=创建消息(messageActionChannelCreate),客户端对
|
|
// monoforum 渲染为 "Direct messages were enabled in this channel."。开关/价格变更的
|
|
// paid_messages_price 只进母广播频道(渲染 "Channel enabled/disabled Direct Messages"),
|
|
// **绝不进 mono**——mono 是 megagroup(非 broadcast),同一 action 会被渲染成"消息免费/
|
|
// 设为 N 星"的错误文案;关闭只靠 monoforumDisabled 状态显示停用页脚。与 postgres 一致。
|
|
if existing := s.channels[channel.LinkedMonoforumID]; existing.ID != 0 && existing.TopMessageID == 0 {
|
|
createMsg, createEvent := s.appendChannelServiceMessageLocked(channel.LinkedMonoforumID, userID, int(time.Now().Unix()), domain.ChannelMessageAction{Type: domain.ChannelActionCreate, Title: existing.Title})
|
|
mono := s.channels[channel.LinkedMonoforumID]
|
|
mono.TopMessageID = createMsg.ID
|
|
mono.Pts = createEvent.Pts
|
|
s.channels[channel.LinkedMonoforumID] = mono
|
|
out.ServiceMessages = append(out.ServiceMessages, domain.SendChannelMessageResult{Channel: cloneChannel(mono), Message: cloneChannelMessage(createMsg), Event: cloneChannelEvent(createEvent)})
|
|
}
|
|
}
|
|
// monoforum 镜像母频道 DM 启用状态到自己的 BroadcastMessagesAllowed(与 postgres 一致):投影时据此
|
|
// 决定是否下发 mono 的 linked_monoforum_id,关闭时双方都隐藏 link → 打开 monoforum 重拉不会清掉
|
|
// MonoforumDisabled,停用页脚保持。内部关联行仍保留以便重新开启复用。
|
|
if channel.LinkedMonoforumID != 0 {
|
|
if mono, ok := s.channels[channel.LinkedMonoforumID]; ok {
|
|
mono.BroadcastMessagesAllowed = channel.BroadcastMessagesAllowed
|
|
s.channels[channel.LinkedMonoforumID] = mono
|
|
}
|
|
}
|
|
if changed && channel.LinkedMonoforumID != 0 {
|
|
action := domain.ChannelMessageAction{
|
|
Type: domain.ChannelActionPaidMessagesPrice,
|
|
BroadcastMessagesAllowed: channel.BroadcastMessagesAllowed,
|
|
Stars: stars,
|
|
}
|
|
parentMsg, parentEvent := s.appendChannelServiceMessageLocked(channelID, userID, int(time.Now().Unix()), action)
|
|
channel.TopMessageID = parentMsg.ID
|
|
channel.Pts = parentEvent.Pts
|
|
out.ServiceMessages = append(out.ServiceMessages, domain.SendChannelMessageResult{Channel: cloneChannel(channel), Message: cloneChannelMessage(parentMsg), Event: cloneChannelEvent(parentEvent)})
|
|
}
|
|
if len(out.ServiceMessages) > 0 {
|
|
out.ServiceMessage = &out.ServiceMessages[0]
|
|
}
|
|
s.channels[channelID] = channel
|
|
out.Channel = cloneChannel(channel)
|
|
return out, nil
|
|
}
|