Initial commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package data
|
||||
|
||||
/** A configured IRC server/network connection. */
|
||||
data class ServerConfig(
|
||||
val id: String, // stable key, e.g. "rizon"
|
||||
val label: String, // display name, e.g. "Rizon"
|
||||
val host: String,
|
||||
val port: Int = 6667,
|
||||
val useTls: Boolean = false,
|
||||
val nick: String,
|
||||
val autoJoinChannels: List<String> = emptyList(),
|
||||
val saslUser: String? = null,
|
||||
val saslPass: String? = null,
|
||||
// Raw IRC commands sent right after registration (001), before auto-join channels.
|
||||
// e.g. "PRIVMSG NickServ :IDENTIFY hunter2" or "NS IDENTIFY hunter2".
|
||||
// This is the "on join perform" list — saved to disk and replayed every connect.
|
||||
val onConnectCommands: List<String> = emptyList()
|
||||
)
|
||||
|
||||
/** True for channel-style targets ('#', '&', '+', '!' prefixes per the IRC spec). */
|
||||
fun isChannelName(name: String): Boolean =
|
||||
name.isNotEmpty() && name[0] in "#&+!"
|
||||
|
||||
enum class MessageKind { CHAT, ACTION, JOIN, PART, QUIT, KICK, MODE, NOTICE, NICK, TOPIC, SYSTEM }
|
||||
|
||||
// Process-wide, so every IrcMessage ever constructed while the app is running gets a
|
||||
// genuinely unique seq, regardless of which buffer/server it belongs to.
|
||||
private val nextMessageSeq = java.util.concurrent.atomic.AtomicLong(0)
|
||||
|
||||
data class IrcMessage(
|
||||
val timestampMillis: Long,
|
||||
val kind: MessageKind,
|
||||
val sender: String?, // nick, or null for system/server lines
|
||||
val rawText: String, // still contains mIRC control codes; parsed at render time
|
||||
val target: String? = null, // e.g. for KICK, the nick that got kicked
|
||||
// Monotonically increasing, guaranteed-unique identity for this message - used as the
|
||||
// LazyColumn item key in ChannelScreen (see there). The old key there was
|
||||
// "${timestampMillis}_${sender}_${rawText.hashCode()}" - in a genuinely busy channel,
|
||||
// two messages sharing the same millisecond, sender, and text (not rare for short
|
||||
// repeated lines - "lol", a single emoji, etc.) would produce the exact same key, and
|
||||
// Compose requires unique keys per item. Not persisted to disk - history reloaded on
|
||||
// restart just gets fresh seq values in load order, which is fine since uniqueness only
|
||||
// needs to hold within a single running session, not across restarts.
|
||||
val seq: Long = nextMessageSeq.getAndIncrement()
|
||||
)
|
||||
|
||||
/** Buffer key: server id + channel/query name (channel names include '#'). */
|
||||
data class BufferKey(val serverId: String, val name: String)
|
||||
|
||||
data class ChannelUser(
|
||||
val nick: String,
|
||||
val isOp: Boolean = false,
|
||||
val isVoice: Boolean = false
|
||||
)
|
||||
|
||||
data class ChannelBuffer(
|
||||
val key: BufferKey,
|
||||
val messages: List<IrcMessage> = emptyList(),
|
||||
val users: List<ChannelUser> = emptyList(),
|
||||
val topic: String = ""
|
||||
)
|
||||
Reference in New Issue
Block a user