notify if mentioned in chat

dbus-notify
Zlatin Balevsky 2022-06-10 09:57:33 +01:00
parent c676098524
commit 5c9368c98f
No known key found for this signature in database
GPG Key ID: A72832072D525E41
8 changed files with 59 additions and 16 deletions

View File

@ -250,6 +250,10 @@ class OptionsController {
model.maxChatLines = maxChatLines model.maxChatLines = maxChatLines
uiSettings.maxChatLines = maxChatLines uiSettings.maxChatLines = maxChatLines
boolean chatNotifyMentions = view.chatNotifyMentionsCheckbox.model.isSelected()
model.chatNotifyMentions = chatNotifyMentions
uiSettings.chatNotifyMentions = chatNotifyMentions
boolean joinDefaultChatRoom = view.joinDefaultChatRoomCheckbox.model.isSelected() boolean joinDefaultChatRoom = view.joinDefaultChatRoomCheckbox.model.isSelected()
model.joinDefaultChatRoom = joinDefaultChatRoom model.joinDefaultChatRoom = joinDefaultChatRoom
settings.joinDefaultChatRoom = joinDefaultChatRoom settings.joinDefaultChatRoom = joinDefaultChatRoom

View File

@ -5,6 +5,7 @@ EXIT=Exit
OPEN_MUWIRE=Open MuWire OPEN_MUWIRE=Open MuWire
NEW_MESSAGE=New MuWire Message NEW_MESSAGE=New MuWire Message
NEW_MESSAGE_FROM=New message from {0} NEW_MESSAGE_FROM=New message from {0}
NEW_CHAT_MENTION=Mentioned in chat
# Startup general # Startup general
MUWIRE_WILL_EXIT=MuWire will now exit. MUWIRE_WILL_EXIT=MuWire will now exit.
@ -399,6 +400,7 @@ OPTIONS_START_CHAT_SERVER_STARTUP=Start chat server on startup
OPTIONS_MAX_CHAT_CONNECTIONS=Maximum chat connections (-1 means unlimited) OPTIONS_MAX_CHAT_CONNECTIONS=Maximum chat connections (-1 means unlimited)
OPTIONS_ADVERTISE_CHAT=Advertise chat ability in search results OPTIONS_ADVERTISE_CHAT=Advertise chat ability in search results
OPTIONS_MAX_CHAT_SCROLLBACK=Maximum lines of scrollback (-1 means unlimited) OPTIONS_MAX_CHAT_SCROLLBACK=Maximum lines of scrollback (-1 means unlimited)
OPTIONS_CHAT_NOTIFY_MENTIONS=Notify when mentioned
OPTIONS_CHAT_WELCOME_FILE=Welcome message file OPTIONS_CHAT_WELCOME_FILE=Welcome message file
OPTIONS_CHAT_JOIN_DEFAULT_ROOM=Automatically join default room on servers OPTIONS_CHAT_JOIN_DEFAULT_ROOM=Automatically join default room on servers
OPTIONS_CHAT_DEFAULT_ROOM=Default chat room (empty for none) OPTIONS_CHAT_DEFAULT_ROOM=Default chat room (empty for none)

View File

@ -91,6 +91,7 @@ class OptionsModel {
@Observable int maxChatConnections @Observable int maxChatConnections
@Observable boolean advertiseChat @Observable boolean advertiseChat
@Observable int maxChatLines @Observable int maxChatLines
@Observable boolean chatNotifyMentions
@Observable String chatWelcomeFile @Observable String chatWelcomeFile
@Observable String defaultChatRoom @Observable String defaultChatRoom
@Observable boolean joinDefaultChatRoom @Observable boolean joinDefaultChatRoom
@ -186,6 +187,7 @@ class OptionsModel {
maxChatConnections = settings.maxChatConnections maxChatConnections = settings.maxChatConnections
advertiseChat = settings.advertiseChat advertiseChat = settings.advertiseChat
maxChatLines = uiSettings.maxChatLines maxChatLines = uiSettings.maxChatLines
chatNotifyMentions = uiSettings.chatNotifyMentions
chatWelcomeFile = settings.chatWelcomeFile?.getAbsolutePath() chatWelcomeFile = settings.chatWelcomeFile?.getAbsolutePath()
defaultChatRoom = settings.defaultChatRoom defaultChatRoom = settings.defaultChatRoom
joinDefaultChatRoom = settings.joinDefaultChatRoom joinDefaultChatRoom = settings.joinDefaultChatRoom

View File

@ -246,6 +246,12 @@ class ChatRoomView {
} }
void appendSay(String text, PersonaOrProfile sender, long timestamp) { void appendSay(String text, PersonaOrProfile sender, long timestamp) {
if (settings.chatNotifyMentions &&
sender.getPersona() != model.core.me &&
text.contains("@${model.core.me.getHumanReadableName()}"))
chatNotificator.notifyMention()
StyledDocument doc = roomTextArea.getStyledDocument() StyledDocument doc = roomTextArea.getStyledDocument()
def label = new DateLabel(timestamp) def label = new DateLabel(timestamp)
def style = doc.addStyle("newStyle", null) def style = doc.addStyle("newStyle", null)

View File

@ -30,6 +30,7 @@ import javax.swing.tree.DefaultMutableTreeNode
import java.awt.GridBagConstraints import java.awt.GridBagConstraints
import java.awt.Image import java.awt.Image
import java.awt.KeyboardFocusManager import java.awt.KeyboardFocusManager
import java.awt.TrayIcon
import java.awt.Window import java.awt.Window
import java.awt.event.ActionEvent import java.awt.event.ActionEvent
import java.awt.event.KeyEvent import java.awt.event.KeyEvent
@ -797,6 +798,7 @@ class MainFrameView {
} }
chatNotificator = new ChatNotificator(application.getMvcGroupManager(), chatNotificator = new ChatNotificator(application.getMvcGroupManager(),
(TrayIcon)application.context.get("tray-icon"),
(Window)application.getWindowManager().findWindow("main-frame"), (Window)application.getWindowManager().findWindow("main-frame"),
(Image) builder.imageIcon("/comment.png").image) (Image) builder.imageIcon("/comment.png").image)
chatFavorites = new ChatFavorites(application) chatFavorites = new ChatFavorites(application)

View File

@ -114,6 +114,7 @@ class OptionsView {
def startChatServerCheckbox def startChatServerCheckbox
def maxChatConnectionsField def maxChatConnectionsField
def chatNotifyMentionsCheckbox
def advertiseChatCheckbox def advertiseChatCheckbox
def maxChatLinesField def maxChatLinesField
def joinDefaultChatRoomCheckbox def joinDefaultChatRoomCheckbox
@ -547,25 +548,36 @@ class OptionsView {
panel (border : titledBorder(title : trans("OPTIONS_CHAT_SETTINGS"), border : etchedBorder(), titlePosition : TitledBorder.TOP), panel (border : titledBorder(title : trans("OPTIONS_CHAT_SETTINGS"), border : etchedBorder(), titlePosition : TitledBorder.TOP),
constraints : gbc(gridx : 0, gridy : 0, fill : GridBagConstraints.HORIZONTAL, weightx: 100)) { constraints : gbc(gridx : 0, gridy : 0, fill : GridBagConstraints.HORIZONTAL, weightx: 100)) {
gridBagLayout() gridBagLayout()
label(text : trans("OPTIONS_START_CHAT_SERVER_STARTUP"), constraints : gbc(gridx: 0, gridy: 0, anchor: GridBagConstraints.LINE_START, weightx: 100)) int j = 0
startChatServerCheckbox = checkBox(selected : bind{model.startChatServer}, constraints : gbc(gridx:2, gridy:0, anchor:GridBagConstraints.LINE_END)) label(text : trans("OPTIONS_START_CHAT_SERVER_STARTUP"), constraints : gbc(gridx: 0, gridy: j, anchor: GridBagConstraints.LINE_START, weightx: 100))
label(text : trans("OPTIONS_MAX_CHAT_CONNECTIONS"), constraints : gbc(gridx: 0, gridy:1, anchor:GridBagConstraints.LINE_START, weightx:100)) startChatServerCheckbox = checkBox(selected : bind{model.startChatServer}, constraints : gbc(gridx:2, gridy:j, anchor:GridBagConstraints.LINE_END))
maxChatConnectionsField = textField(text : bind {model.maxChatConnections}, constraints : gbc(gridx: 2, gridy : 1, anchor:GridBagConstraints.LINE_END), j++
label(text : trans("OPTIONS_MAX_CHAT_CONNECTIONS"), constraints : gbc(gridx: 0, gridy:j, anchor:GridBagConstraints.LINE_START, weightx:100))
maxChatConnectionsField = textField(text : bind {model.maxChatConnections}, constraints : gbc(gridx: 2, gridy : j, anchor:GridBagConstraints.LINE_END),
columns: COLUMNS, horizontalAlignment: JTextField.RIGHT) columns: COLUMNS, horizontalAlignment: JTextField.RIGHT)
label(text : trans("OPTIONS_ADVERTISE_CHAT"), constraints : gbc(gridx: 0, gridy:2, anchor:GridBagConstraints.LINE_START, weightx:100)) j++
advertiseChatCheckbox = checkBox(selected : bind{model.advertiseChat}, constraints : gbc(gridx:2, gridy:2, anchor:GridBagConstraints.LINE_END)) label(text : trans("OPTIONS_ADVERTISE_CHAT"), constraints : gbc(gridx: 0, gridy:j, anchor:GridBagConstraints.LINE_START, weightx:100))
label(text : trans("OPTIONS_MAX_CHAT_SCROLLBACK"), constraints : gbc(gridx:0, gridy:3, anchor : GridBagConstraints.LINE_START, weightx: 100)) advertiseChatCheckbox = checkBox(selected : bind{model.advertiseChat}, constraints : gbc(gridx:2, gridy:j, anchor:GridBagConstraints.LINE_END))
maxChatLinesField = textField(text : bind{model.maxChatLines}, constraints : gbc(gridx:2, gridy: 3, anchor: GridBagConstraints.LINE_END), j++
label(text : trans("OPTIONS_MAX_CHAT_SCROLLBACK"), constraints : gbc(gridx:0, gridy:j, anchor : GridBagConstraints.LINE_START, weightx: 100))
maxChatLinesField = textField(text : bind{model.maxChatLines}, constraints : gbc(gridx:2, gridy: j, anchor: GridBagConstraints.LINE_END),
columns: COLUMNS, horizontalAlignment: JTextField.RIGHT) columns: COLUMNS, horizontalAlignment: JTextField.RIGHT)
label(text: trans("OPTIONS_CHAT_JOIN_DEFAULT_ROOM"), constraints: gbc(gridx: 0, gridy: 4, anchor: GridBagConstraints.LINE_START, weightx: 100)) j++
joinDefaultChatRoomCheckbox = checkBox(selected: bind{model.joinDefaultChatRoom}, constraints: gbc(gridx: 2, gridy: 4, anchor: GridBagConstraints.LINE_END)) label(text : trans("OPTIONS_CHAT_NOTIFY_MENTIONS"), constraints: gbc(gridx: 0, gridy: j, anchor: GridBagConstraints.LINE_START, weightx: 100))
label(text: trans("OPTIONS_CHAT_DEFAULT_ROOM"), constraints: gbc(gridx: 0, gridy: 5, anchor: GridBagConstraints.LINE_START, weightx: 100)) chatNotifyMentionsCheckbox = checkBox(selected: bind {model.chatNotifyMentions}, constraints: gbc(gridx:2, gridy:j, anchor: GridBagConstraints.LINE_END))
defaultChatRoomField = textField(text : bind { model.defaultChatRoom}, constraints: gbc(gridx: 2, gridy: 5, anchor: GridBagConstraints.LINE_END), j++
label(text: trans("OPTIONS_CHAT_JOIN_DEFAULT_ROOM"), constraints: gbc(gridx: 0, gridy: j, anchor: GridBagConstraints.LINE_START, weightx: 100))
joinDefaultChatRoomCheckbox = checkBox(selected: bind{model.joinDefaultChatRoom}, constraints: gbc(gridx: 2, gridy: j, anchor: GridBagConstraints.LINE_END))
j++
label(text: trans("OPTIONS_CHAT_DEFAULT_ROOM"), constraints: gbc(gridx: 0, gridy: j, anchor: GridBagConstraints.LINE_START, weightx: 100))
defaultChatRoomField = textField(text : bind { model.defaultChatRoom}, constraints: gbc(gridx: 2, gridy: j, anchor: GridBagConstraints.LINE_END),
columns: COLUMNS * 2, horizontalAlignment: JTextField.RIGHT) columns: COLUMNS * 2, horizontalAlignment: JTextField.RIGHT)
j++
if (!isAqua()) { if (!isAqua()) {
label(text : trans("OPTIONS_CHAT_WELCOME_FILE"), constraints : gbc(gridx : 0, gridy : 6, anchor : GridBagConstraints.LINE_START, weightx: 100)) label(text : trans("OPTIONS_CHAT_WELCOME_FILE"), constraints : gbc(gridx : 0, gridy : j, anchor : GridBagConstraints.LINE_START, weightx: 100))
label(text : bind {model.chatWelcomeFile}, constraints : gbc(gridx : 1, gridy : 6)) label(text : bind {model.chatWelcomeFile}, constraints : gbc(gridx : 1, gridy : j))
button(text : trans("CHOOSE"), constraints : gbc(gridx : 2, gridy : 6, anchor : GridBagConstraints.LINE_END), chooseChatFileAction) button(text : trans("CHOOSE"), constraints : gbc(gridx : 2, gridy : j, anchor : GridBagConstraints.LINE_END), chooseChatFileAction)
j++
} }
} }
panel (border : titledBorder(title : trans("OPTIONS_MESSAGING_SETTINGS"), border : etchedBorder(), titlePosition : TitledBorder.TOP), panel (border : titledBorder(title : trans("OPTIONS_MESSAGING_SETTINGS"), border : etchedBorder(), titlePosition : TitledBorder.TOP),

View File

@ -9,6 +9,9 @@ import javax.swing.JTabbedPane
import griffon.core.mvc.MVCGroupManager import griffon.core.mvc.MVCGroupManager
import static com.muwire.gui.Translator.trans
import java.awt.TrayIcon
import java.awt.Window import java.awt.Window
class ChatNotificator { class ChatNotificator {
@ -20,6 +23,7 @@ class ChatNotificator {
private final MVCGroupManager groupManager private final MVCGroupManager groupManager
private final Window window private final Window window
private final Image image private final Image image
private final TrayIcon trayIcon
private boolean chatInFocus private boolean chatInFocus
private String currentServerTab private String currentServerTab
@ -29,10 +33,17 @@ class ChatNotificator {
private Listener listener private Listener listener
ChatNotificator(MVCGroupManager groupManager, Window window, Image image) { ChatNotificator(MVCGroupManager groupManager, TrayIcon trayIcon, Window window, Image image) {
this.groupManager = groupManager this.groupManager = groupManager
this.window = window this.window = window
this.image = image this.image = image
this.trayIcon = trayIcon
}
void notifyMention() {
if (trayIcon == null)
return
trayIcon.displayMessage(trans("NEW_CHAT_MENTION"), trans("NEW_CHAT_MENTION"), TrayIcon.MessageType.INFO)
} }
void serverTabChanged(JTabbedPane source) { void serverTabChanged(JTabbedPane source) {

View File

@ -29,6 +29,7 @@ class UISettings {
boolean storeSearchHistory boolean storeSearchHistory
boolean groupByFile boolean groupByFile
int maxChatLines int maxChatLines
boolean chatNotifyMentions
Set<String> searchHistory Set<String> searchHistory
Set<String> openTabs Set<String> openTabs
boolean messageNotifications boolean messageNotifications
@ -57,6 +58,7 @@ class UISettings {
storeSearchHistory = Boolean.parseBoolean(props.getProperty("storeSearchHistory","true")) storeSearchHistory = Boolean.parseBoolean(props.getProperty("storeSearchHistory","true"))
groupByFile = Boolean.parseBoolean(props.getProperty("groupByFile","false")) groupByFile = Boolean.parseBoolean(props.getProperty("groupByFile","false"))
maxChatLines = Integer.parseInt(props.getProperty("maxChatLines","-1")) maxChatLines = Integer.parseInt(props.getProperty("maxChatLines","-1"))
chatNotifyMentions = Boolean.parseBoolean(props.getProperty("chatNotifyMentions", "true"))
mainFrameX = Integer.parseInt(props.getProperty("mainFrameX","-1")) mainFrameX = Integer.parseInt(props.getProperty("mainFrameX","-1"))
mainFrameY = Integer.parseInt(props.getProperty("mainFrameY","-1")) mainFrameY = Integer.parseInt(props.getProperty("mainFrameY","-1"))
@ -91,6 +93,8 @@ class UISettings {
props.setProperty("storeSearchHistory", String.valueOf(storeSearchHistory)) props.setProperty("storeSearchHistory", String.valueOf(storeSearchHistory))
props.setProperty("groupByFile", String.valueOf(groupByFile)) props.setProperty("groupByFile", String.valueOf(groupByFile))
props.setProperty("maxChatLines", String.valueOf(maxChatLines)) props.setProperty("maxChatLines", String.valueOf(maxChatLines))
props.setProperty("chatNotifyMentions", String.valueOf(chatNotifyMentions))
props.setProperty("fontStyle", String.valueOf(fontStyle)) props.setProperty("fontStyle", String.valueOf(fontStyle))
if (font != null) if (font != null)
props.setProperty("font", font) props.setProperty("font", font)