// IRCop tools if (showIrcOpTools) { ModalBottomSheet(onDismissRequest = { showIrcOpTools = false }) { val scrollState = rememberScrollState() Column( Modifier .fillMaxWidth() .fillMaxHeight(0.92f) .padding(16.dp) .navigationBarsPadding() .imePadding() .verticalScroll(scrollState), verticalArrangement = Arrangement.spacedBy(14.dp) ) { Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) { Icon(Icons.Default.AdminPanelSettings, contentDescription = null, tint = MaterialTheme.colorScheme.primary) Text("IRCop tools", style = MaterialTheme.typography.titleLarge) } Text("$selNetName", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) HorizontalDivider() var opTarget by remember { mutableStateOf("") } var opReason by remember { mutableStateOf("") } var opMask by remember { mutableStateOf("") } var opServer by remember { mutableStateOf("") } var opMessage by remember { mutableStateOf("") } // Target / Reason fields Text("Target", fontWeight = FontWeight.Bold) OutlinedTextField( value = opTarget, onValueChange = { opTarget = it }, modifier = Modifier.fillMaxWidth(), singleLine = true, label = { Text("Nick or host mask") } ) OutlinedTextField( value = opReason, onValueChange = { opReason = it }, modifier = Modifier.fillMaxWidth(), singleLine = true, label = { Text("Reason") } ) // Kill / K-line / Z-line Text("Punishments", fontWeight = FontWeight.Bold) Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { Button( onClick = { val t = opTarget.trim() if (t.isNotBlank()) { val r = opReason.trim().ifBlank { "No reason" } onSend("/kill $t $r") showIrcOpTools = false } }, enabled = opTarget.isNotBlank() ) { Text("Kill") } OutlinedButton( onClick = { val t = opTarget.trim() if (t.isNotBlank()) { val r = opReason.trim().ifBlank { "No reason" } onSend("/kline $t $r") showIrcOpTools = false } }, enabled = opTarget.isNotBlank() ) { Text("K-line") } OutlinedButton( onClick = { val t = opMask.trim().ifBlank { opTarget.trim() } if (t.isNotBlank()) { val r = opReason.trim().ifBlank { "No reason" } onSend("/zline $t $r") showIrcOpTools = false } }, enabled = opTarget.isNotBlank() ) { Text("Z-line") } OutlinedButton( onClick = { val t = opTarget.trim() if (t.isNotBlank()) { val r = opReason.trim().ifBlank { "No reason" } onSend("/gline $t $r") showIrcOpTools = false } }, enabled = opTarget.isNotBlank() ) { Text("G-line") } } Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { OutlinedButton( onClick = { val t = opTarget.trim() if (t.isNotBlank()) { val r = opReason.trim().ifBlank { "No reason" } onSend("/shun $t $r") } }, enabled = opTarget.isNotBlank() ) { Text("Shun") } OutlinedButton( onClick = { val t = opTarget.trim() if (t.isNotBlank()) { val r = opReason.trim().ifBlank { "No reason" } onSend("/dline $t $r") } }, enabled = opTarget.isNotBlank() ) { Text("D-line") } } HorizontalDivider() // Force join/part Text("Force join / part", fontWeight = FontWeight.Bold) Row( Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically ) { OutlinedTextField( value = opServer, onValueChange = { opServer = it }, modifier = Modifier.weight(1f), singleLine = true, label = { Text("Channel") } ) Button( onClick = { val t = opTarget.trim(); val ch = opServer.trim() if (t.isNotBlank() && ch.isNotBlank()) onSend("/sajoin $t $ch") }, enabled = opTarget.isNotBlank() && opServer.isNotBlank() ) { Text("SAJoin") } OutlinedButton( onClick = { val t = opTarget.trim(); val ch = opServer.trim() if (t.isNotBlank() && ch.isNotBlank()) onSend("/sapart $t $ch") }, enabled = opTarget.isNotBlank() && opServer.isNotBlank() ) { Text("SAPart") } } HorizontalDivider() // Broadcast messages Text("Broadcast", fontWeight = FontWeight.Bold) OutlinedTextField( value = opMessage, onValueChange = { opMessage = it }, modifier = Modifier.fillMaxWidth(), singleLine = true, label = { Text("Message") } ) Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { Button( onClick = { if (opMessage.isNotBlank()) onSend("/wallops ${opMessage.trim()}") }, enabled = opMessage.isNotBlank() ) { Text("WALLOPS") } OutlinedButton( onClick = { if (opMessage.isNotBlank()) onSend("/globops ${opMessage.trim()}") }, enabled = opMessage.isNotBlank() ) { Text("GLOBOPS") } OutlinedButton( onClick = { if (opMessage.isNotBlank()) onSend("/locops ${opMessage.trim()}") }, enabled = opMessage.isNotBlank() ) { Text("LOCOPS") } } HorizontalDivider() // Server queries Text("Server queries", fontWeight = FontWeight.Bold) Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { OutlinedButton(onClick = { onSend("/motd"); showIrcOpTools = false }) { Text("MOTD") } OutlinedButton(onClick = { onSend("/admin"); showIrcOpTools = false }) { Text("ADMIN") } OutlinedButton(onClick = { onSend("/stats u"); showIrcOpTools = false }) { Text("Uptime") } OutlinedButton(onClick = { onSend("/stats l"); showIrcOpTools = false }) { Text("Links") } } Spacer(Modifier.height(8.dp)) } } }