Files
SashegDev 096c4d0a2d Initial commit: JustAMessenger v0.1.0
Серверная часть (Go):
- WebSocket сервер с бинарным протоколом
- XChaCha20-Poly1305 шифрование
- zstd сжатие с дедупликацией (64KB чанки)
- SQLite хранилище (WAL режим)
- Управление гильдиями, каналами, ролями
- Федерация между серверами (ed25519)
- REST API + WebSocket endpoints

Клиентская часть (Flutter):
- Material Design 3 тёмная тема (Discord-like)
- WebSocket соединение с сервером
- Экраны: сплэш, логин, домашний, гильдии, чат
- Модели: пользователи, гильдии, каналы, сообщения, роли
- Сервисы: соединение, API, криптография, тема
- Виджеты: иконки гильдий, сообщения, ввод чата
- Web сборка (PWA)

Документация:
- AGENTS.md — контекст для ИИ ассистентов
- docs/protocol.md — спецификация протокола
2026-06-06 22:39:14 +00:00

136 lines
3.1 KiB
Go

package channel
import (
"errors"
"github.com/google/uuid"
"github.com/justamessenger/server/internal/database"
"github.com/justamessenger/server/internal/models"
)
type Manager struct {
db *database.DB
}
func NewManager(db *database.DB) *Manager {
return &Manager{db: db}
}
func (m *Manager) Create(guildID, categoryID, name, channelType, topic string, position int) (*models.Channel, error) {
id := uuid.New().String()
_, err := m.db.Exec(
`INSERT INTO channels (id, guild_id, category_id, name, type, topic, position)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
id, guildID, categoryID, name, channelType, topic, position,
)
if err != nil {
return nil, err
}
return m.Get(id)
}
func (m *Manager) Get(id string) (*models.Channel, error) {
row := m.db.QueryRow(
`SELECT id, guild_id, category_id, name, type, topic, position, created_at
FROM channels WHERE id = ?`, id,
)
c := &models.Channel{}
err := row.Scan(&c.ID, &c.GuildID, &c.Category, &c.Name, &c.Type, &c.Topic, &c.Position, &c.CreatedAt)
if err != nil {
return nil, err
}
return c, nil
}
func (m *Manager) ListByGuild(guildID string) ([]*models.Channel, error) {
rows, err := m.db.Query(
`SELECT id, guild_id, category_id, name, type, topic, position, created_at
FROM channels WHERE guild_id = ? ORDER BY position`, guildID,
)
if err != nil {
return nil, err
}
defer rows.Close()
var channels []*models.Channel
for rows.Next() {
c := &models.Channel{}
if err := rows.Scan(&c.ID, &c.GuildID, &c.Category, &c.Name, &c.Type, &c.Topic, &c.Position, &c.CreatedAt); err != nil {
return nil, err
}
channels = append(channels, c)
}
return channels, nil
}
func (m *Manager) Update(id, name, topic string, position int) error {
result, err := m.db.Exec(
`UPDATE channels SET name = ?, topic = ?, position = ? WHERE id = ?`,
name, topic, position, id,
)
if err != nil {
return err
}
affected, _ := result.RowsAffected()
if affected == 0 {
return errors.New("channel not found")
}
return nil
}
func (m *Manager) Delete(id string) error {
result, err := m.db.Exec(`DELETE FROM channels WHERE id = ?`, id)
if err != nil {
return err
}
affected, _ := result.RowsAffected()
if affected == 0 {
return errors.New("channel not found")
}
return nil
}
func (m *Manager) CreateCategory(guildID, name string, position int) (string, error) {
id := uuid.New().String()
_, err := m.db.Exec(
`INSERT INTO categories (id, guild_id, name, position) VALUES (?, ?, ?, ?)`,
id, guildID, name, position,
)
if err != nil {
return "", err
}
return id, nil
}
func (m *Manager) ListCategories(guildID string) ([]*struct {
ID string
Name string
Position int
}, error) {
rows, err := m.db.Query(
`SELECT id, name, position FROM categories WHERE guild_id = ? ORDER BY position`, guildID,
)
if err != nil {
return nil, err
}
defer rows.Close()
var cats []*struct {
ID string
Name string
Position int
}
for rows.Next() {
var c struct {
ID string
Name string
Position int
}
if err := rows.Scan(&c.ID, &c.Name, &c.Position); err != nil {
return nil, err
}
cats = append(cats, &c)
}
return cats, nil
}