mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-02 12:50:16 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
d92b43e91b
@ -15,6 +15,7 @@ import net.mamoe.mirai.console.graphical.stylesheet.PrimaryStyleSheet
|
|||||||
import net.mamoe.mirai.console.graphical.view.Decorator
|
import net.mamoe.mirai.console.graphical.view.Decorator
|
||||||
import tornadofx.App
|
import tornadofx.App
|
||||||
import tornadofx.find
|
import tornadofx.find
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
//object MiraiGraphicalLoader {
|
//object MiraiGraphicalLoader {
|
||||||
// @JvmStatic
|
// @JvmStatic
|
||||||
@ -33,5 +34,6 @@ class MiraiGraphicalUI : App(Decorator::class, PrimaryStyleSheet::class) {
|
|||||||
override fun stop() {
|
override fun stop() {
|
||||||
super.stop()
|
super.stop()
|
||||||
MiraiConsole.stop()
|
MiraiConsole.stop()
|
||||||
|
exitProcess(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,10 @@ import javafx.collections.ObservableList
|
|||||||
import javafx.stage.Modality
|
import javafx.stage.Modality
|
||||||
import javafx.stage.StageStyle
|
import javafx.stage.StageStyle
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.console.command.CommandManager
|
import net.mamoe.mirai.console.command.CommandManager
|
||||||
|
import net.mamoe.mirai.console.command.CommandManager.runCommand
|
||||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||||
import net.mamoe.mirai.console.graphical.model.*
|
import net.mamoe.mirai.console.graphical.model.*
|
||||||
import net.mamoe.mirai.console.graphical.view.dialog.InputDialog
|
import net.mamoe.mirai.console.graphical.view.dialog.InputDialog
|
||||||
@ -25,7 +27,7 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
|
|||||||
private val settingModel = find<GlobalSettingModel>()
|
private val settingModel = find<GlobalSettingModel>()
|
||||||
private val loginSolver = GraphicalLoginSolver()
|
private val loginSolver = GraphicalLoginSolver()
|
||||||
private val cache = mutableMapOf<Long, BotModel>()
|
private val cache = mutableMapOf<Long, BotModel>()
|
||||||
val mainLog = observableListOf<String>()
|
val mainLog = observableListOf<Pair<String, String>>()
|
||||||
|
|
||||||
|
|
||||||
val botList = observableListOf<BotModel>()
|
val botList = observableListOf<BotModel>()
|
||||||
@ -41,7 +43,16 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
|
|||||||
CommandManager.runCommand(ConsoleCommandSender, "/login $qq $psd")
|
CommandManager.runCommand(ConsoleCommandSender, "/login $qq $psd")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendCommand(command: String) = CommandManager.runCommand(ConsoleCommandSender, command)
|
fun logout(qq: Long) {
|
||||||
|
cache.remove(qq)?.apply {
|
||||||
|
botList.remove(this)
|
||||||
|
if (botProperty.value != null && bot.isActive) {
|
||||||
|
bot.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendCommand(command: String) = runCommand(ConsoleCommandSender, command)
|
||||||
|
|
||||||
override fun pushLog(identity: Long, message: String) = Platform.runLater {
|
override fun pushLog(identity: Long, message: String) = Platform.runLater {
|
||||||
this.pushLog(LogPriority.INFO, "", identity, message)
|
this.pushLog(LogPriority.INFO, "", identity, message)
|
||||||
@ -58,16 +69,18 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
|
|||||||
} else {
|
} else {
|
||||||
cache[identity]?.logHistory
|
cache[identity]?.logHistory
|
||||||
}?.apply {
|
}?.apply {
|
||||||
add("[$time] $identityStr $message")
|
add("[$time] $identityStr $message" to priority.name)
|
||||||
trim()
|
trim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun prePushBot(identity: Long) = Platform.runLater {
|
override fun prePushBot(identity: Long) = Platform.runLater {
|
||||||
BotModel(identity).also {
|
if (!cache.containsKey(identity)) {
|
||||||
cache[identity] = it
|
BotModel(identity).also {
|
||||||
botList.add(it)
|
cache[identity] = it
|
||||||
|
botList.add(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class BotModel(val uin: Long) {
|
|||||||
val botProperty = SimpleObjectProperty<Bot>(null)
|
val botProperty = SimpleObjectProperty<Bot>(null)
|
||||||
var bot: Bot by botProperty
|
var bot: Bot by botProperty
|
||||||
|
|
||||||
val logHistory = observableListOf<String>()
|
val logHistory = observableListOf<Pair<String, String>>()
|
||||||
val admins = observableListOf<Long>()
|
val admins = observableListOf<Long>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +69,21 @@ class PrimaryStyleSheet : BaseStyleSheet() {
|
|||||||
backgroundColor += c(100, 100, 100, 0.4)
|
backgroundColor += c(100, 100, 100, 0.4)
|
||||||
backgroundRadius += box(5.px)
|
backgroundRadius += box(5.px)
|
||||||
|
|
||||||
textFill = c(fontColor)
|
label {
|
||||||
fontWeight = FontWeight.BOLD
|
textFill = c(fontColor)
|
||||||
|
fontWeight = FontWeight.BOLD
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
opacity = 0.0
|
||||||
|
backgroundRadius += box(10.px)
|
||||||
|
backgroundColor += c(fontColor, 0.1)
|
||||||
|
cursor = Cursor.HAND
|
||||||
|
|
||||||
|
and(hover) {
|
||||||
|
opacity = 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,6 +124,15 @@ class PrimaryStyleSheet : BaseStyleSheet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
listCell {
|
listCell {
|
||||||
|
|
||||||
|
and(":WARNING") {
|
||||||
|
backgroundColor += c("FFFF00", 0.3) // Yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
and(":ERROR") {
|
||||||
|
backgroundColor += c("FF0000", 0.3) // Red
|
||||||
|
}
|
||||||
|
|
||||||
and(":selected") {
|
and(":selected") {
|
||||||
backgroundColor += c(stressColor, 1.0)
|
backgroundColor += c(stressColor, 1.0)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package net.mamoe.mirai.console.graphical.util
|
||||||
|
|
||||||
|
import com.jfoenix.svg.SVGGlyph
|
||||||
|
import javafx.scene.paint.Color
|
||||||
|
|
||||||
|
class SVG {
|
||||||
|
companion object {
|
||||||
|
var close = SVGGlyph(
|
||||||
|
0,
|
||||||
|
"CLOSE",
|
||||||
|
"M810 274l-238 238 238 238-60 60-238-238-238 238-60-60 238-238-238-238 60-60 238 238 238-238z",
|
||||||
|
Color.WHITE
|
||||||
|
).apply { setSize(8.0, 8.0) }
|
||||||
|
}
|
||||||
|
}
|
@ -5,19 +5,24 @@ import com.jfoenix.controls.JFXListCell
|
|||||||
import javafx.collections.ObservableList
|
import javafx.collections.ObservableList
|
||||||
import javafx.geometry.Insets
|
import javafx.geometry.Insets
|
||||||
import javafx.geometry.Pos
|
import javafx.geometry.Pos
|
||||||
|
import javafx.scene.control.Alert
|
||||||
|
import javafx.scene.control.ButtonType
|
||||||
import javafx.scene.control.Tab
|
import javafx.scene.control.Tab
|
||||||
import javafx.scene.control.TabPane
|
import javafx.scene.control.TabPane
|
||||||
import javafx.scene.image.Image
|
import javafx.scene.image.Image
|
||||||
|
import javafx.scene.input.Clipboard
|
||||||
import javafx.scene.input.KeyCode
|
import javafx.scene.input.KeyCode
|
||||||
|
import javafx.scene.layout.Priority
|
||||||
import javafx.stage.FileChooser
|
import javafx.stage.FileChooser
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
||||||
import net.mamoe.mirai.console.graphical.model.BotModel
|
import net.mamoe.mirai.console.graphical.model.BotModel
|
||||||
|
import net.mamoe.mirai.console.graphical.util.*
|
||||||
import net.mamoe.mirai.console.graphical.util.jfxButton
|
import net.mamoe.mirai.console.graphical.util.jfxButton
|
||||||
import net.mamoe.mirai.console.graphical.util.jfxListView
|
import net.mamoe.mirai.console.graphical.util.jfxListView
|
||||||
import net.mamoe.mirai.console.graphical.util.jfxTabPane
|
import net.mamoe.mirai.console.graphical.util.jfxTabPane
|
||||||
import net.mamoe.mirai.console.graphical.util.myButtonBar
|
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
import tornadofx.Stylesheet.Companion.contextMenu
|
||||||
|
|
||||||
class PrimaryView : View() {
|
class PrimaryView : View() {
|
||||||
|
|
||||||
@ -72,8 +77,27 @@ class PrimaryView : View() {
|
|||||||
override fun updateItem(item: BotModel?, empty: Boolean) {
|
override fun updateItem(item: BotModel?, empty: Boolean) {
|
||||||
super.updateItem(item, empty)
|
super.updateItem(item, empty)
|
||||||
if (item != null && !empty) {
|
if (item != null && !empty) {
|
||||||
graphic = null
|
graphic = hbox {
|
||||||
text = item.uin.toString()
|
|
||||||
|
alignment = Pos.CENTER_LEFT
|
||||||
|
|
||||||
|
label(item.uin.toString())
|
||||||
|
pane {
|
||||||
|
hgrow = Priority.ALWAYS
|
||||||
|
}
|
||||||
|
jfxButton(graphic = SVG.close) {
|
||||||
|
buttonType = JFXButton.ButtonType.FLAT
|
||||||
|
tooltip("退出登录")
|
||||||
|
}.action {
|
||||||
|
alert(Alert.AlertType.CONFIRMATION, "${item.uin}将会退出登录,是否确认") {
|
||||||
|
if (it == ButtonType.OK) {
|
||||||
|
tab?.close()
|
||||||
|
controller.logout(item.uin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text = ""
|
||||||
} else {
|
} else {
|
||||||
graphic = null
|
graphic = null
|
||||||
text = ""
|
text = ""
|
||||||
@ -129,7 +153,7 @@ private fun TabPane.fixedTab(title: String) = tab(title) { isClosable = false }
|
|||||||
|
|
||||||
private fun TabPane.logTab(
|
private fun TabPane.logTab(
|
||||||
text: String? = null,
|
text: String? = null,
|
||||||
logs: ObservableList<String>,
|
logs: ObservableList<Pair<String, String>>,
|
||||||
closeable: Boolean = true,
|
closeable: Boolean = true,
|
||||||
op: Tab.() -> Unit = {}
|
op: Tab.() -> Unit = {}
|
||||||
) = tab(text) {
|
) = tab(text) {
|
||||||
@ -152,7 +176,7 @@ private fun TabPane.logTab(
|
|||||||
path.firstOrNull()?.run {
|
path.firstOrNull()?.run {
|
||||||
if (!exists()) createNewFile()
|
if (!exists()) createNewFile()
|
||||||
writer().use {
|
writer().use {
|
||||||
logs.forEach { log -> it.appendln(log) }
|
logs.forEach { log -> it.appendln(log.first) }
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
} ?: false
|
} ?: false
|
||||||
@ -166,9 +190,22 @@ private fun TabPane.logTab(
|
|||||||
|
|
||||||
fitToParentSize()
|
fitToParentSize()
|
||||||
cellFormat {
|
cellFormat {
|
||||||
graphic = label(it) {
|
|
||||||
|
addPseudoClass(it.second)
|
||||||
|
|
||||||
|
graphic = label(it.first) {
|
||||||
maxWidthProperty().bind(this@listview.widthProperty())
|
maxWidthProperty().bind(this@listview.widthProperty())
|
||||||
isWrapText = true
|
isWrapText = true
|
||||||
|
|
||||||
|
|
||||||
|
contextmenu {
|
||||||
|
item("复制").action {
|
||||||
|
Clipboard.getSystemClipboard().putString(it.first)
|
||||||
|
}
|
||||||
|
item("删除").action {
|
||||||
|
logs.remove(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,9 +307,11 @@ private val trySetAccessibleMethod: Method? = runCatching {
|
|||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
|
|
||||||
private fun Constructor<out PluginBase>.againstPermission() {
|
private fun Constructor<out PluginBase>.againstPermission() {
|
||||||
trySetAccessibleMethod?.let { it.invoke(this, true) }
|
kotlin.runCatching {
|
||||||
?: kotlin.runCatching {
|
trySetAccessibleMethod?.let { it.invoke(this) }
|
||||||
@Suppress("DEPRECATED")
|
?: kotlin.runCatching {
|
||||||
this.isAccessible = true
|
@Suppress("DEPRECATED")
|
||||||
}
|
this.isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user