diff options
| author | 2025-12-31 14:15:42 +0300 | |
|---|---|---|
| committer | 2025-12-31 14:15:42 +0300 | |
| commit | 8c0b8ad931045c70845f662238230edb81f8cd94 (patch) | |
| tree | 3bfa44e03bae220fc1233c02d716d0baa27efa3d /internal/chat | |
| parent | немного поправил отображение (diff) | |
| download | qchat-8c0b8ad931045c70845f662238230edb81f8cd94.tar.gz qchat-8c0b8ad931045c70845f662238230edb81f8cd94.tar.bz2 qchat-8c0b8ad931045c70845f662238230edb81f8cd94.tar.xz qchat-8c0b8ad931045c70845f662238230edb81f8cd94.zip | |
Сделал корректную работу с терминалом и историю
Diffstat (limited to '')
| -rw-r--r-- | internal/chat/chan.go | 38 | ||||
| -rw-r--r-- | internal/chat/chat.go | 17 | ||||
| -rw-r--r-- | internal/chat/logs.go | 44 | ||||
| -rw-r--r-- | internal/chat/presence.go | 4 |
4 files changed, 97 insertions, 6 deletions
diff --git a/internal/chat/chan.go b/internal/chat/chan.go index bc2b70f..be9ae71 100644 --- a/internal/chat/chan.go +++ b/internal/chat/chan.go @@ -11,6 +11,7 @@ type Channel struct { Name string Users map[*User]struct{} Events chan any + Log Logs mu sync.RWMutex } @@ -21,6 +22,7 @@ func (c *Channel) Listen(ctx context.Context) { return case ev := <-c.Events: c.processEvent(ev) + c.processLog(ev) } } } @@ -42,6 +44,37 @@ func (c *Channel) processEvent(ev any) { } } +func (c *Channel) processLog(ev any) { + switch ev := ev.(type) { + case UserJoined: + c.Log.Append(LogEntry{ + Username: ev.User.NUsername(), + Time: ev.Time, + Type: TypeJoined, + }) + case UserLeft: + c.Log.Append(LogEntry{ + Username: ev.User.NUsername(), + Time: ev.Time, + Type: TypeLeft, + }) + case Message: + c.Log.Append(LogEntry{ + Username: ev.User.NUsername(), + Time: ev.Time, + Message: ev.Message, + Type: TypeMessage, + }) + case SelfMessage: + c.Log.Append(LogEntry{ + Username: ev.User.NUsername(), + Time: time.Now(), + Message: "/me " + ev.Message, + Type: TypeMessage, + }) + } +} + func (c *Channel) Join(u *User) { c.mu.Lock() defer c.mu.Unlock() @@ -56,6 +89,11 @@ func (c *Channel) Join(u *User) { } c.Users[u] = struct{}{} + + // Отправляем при подключении последние 20 сообщений + u.Events <- UserLogs{ + Logs: c.Log.Get(), + } } func (c *Channel) Leave(u *User) { diff --git a/internal/chat/chat.go b/internal/chat/chat.go index 4a639ba..1639d6b 100644 --- a/internal/chat/chat.go +++ b/internal/chat/chat.go @@ -15,6 +15,12 @@ var ( "/join [chan] - change current channel to [chan]\n" + "/chans - list all chans\n" + "/users - list all online users\n" + + "/me [message] - display message like from third person\n" + + "Formatting:\n" + + "- *Bold*\n" + + "- +Italic+\n" + + "- -Striked-\n" + + "- _Underline_\n" + "ctrl+c - leave chat" ) @@ -55,18 +61,18 @@ func (c *Chat) NewUser(username, identify string) *User { Events: make(chan any, 32), mu: sync.RWMutex{}, } + u.Events <- SystemMessage{ + Message: fmt.Sprintf("Connected to %s chat server...\nType /help command for list available commands.", c.cfg.Server.Name), + } ch := c.GetChannel("main") + if ch != nil { u.JoinChan(ch) } c.users[u] = struct{}{} - u.Events <- SystemMessage{ - Message: fmt.Sprintf("Connected to %s chat server...", c.cfg.Server.Name), - } - return u } @@ -170,8 +176,7 @@ func (c *Chat) Input(ctx context.Context, user *User, input string) { newChan = c.NewChannel(ctx, newChanName) } user.CurrentChan.Leave(user) - user.CurrentChan = newChan - newChan.Join(user) + user.JoinChan(newChan) default: c.Message(user, input) } diff --git a/internal/chat/logs.go b/internal/chat/logs.go new file mode 100644 index 0000000..09d60fe --- /dev/null +++ b/internal/chat/logs.go @@ -0,0 +1,44 @@ +package chat + +import "time" + +type Logs struct { + entries [20]LogEntry + start int +} + +func (l *Logs) Append(le LogEntry) { + l.entries[l.start] = le + l.start++ + if l.start == len(l.entries) { + l.start = 0 + } +} + +func (l *Logs) Get() []LogEntry { + result := make([]LogEntry, 0, len(l.entries)) + for i := l.start; i < len(l.entries); i++ { + result = append(result, l.entries[i]) + } + for i := 0; i < l.start; i++ { + result = append(result, l.entries[i]) + } + + return result +} + +type LogEntry struct { + Username string + Time time.Time + Message string + Type LogEntryType +} + +type LogEntryType int + +const ( + TypeNone LogEntryType = iota + TypeJoined + TypeLeft + TypeMessage +) diff --git a/internal/chat/presence.go b/internal/chat/presence.go index 995f214..1057a11 100644 --- a/internal/chat/presence.go +++ b/internal/chat/presence.go @@ -15,3 +15,7 @@ type UserLeft struct { Chan *Channel Time time.Time } + +type UserLogs struct { + Logs []LogEntry +} |
