aboutsummaryrefslogtreecommitdiff
path: root/internal/chat
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--internal/chat/chan.go38
-rw-r--r--internal/chat/chat.go17
-rw-r--r--internal/chat/logs.go44
-rw-r--r--internal/chat/presence.go4
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
+}