From daa3a293f20dda8ea35a2eab0fa4aeaefa10805c Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Fri, 15 Nov 2019 13:15:27 +0000 Subject: [PATCH] new messages update taskbar badge --- .../com/muwire/gui/ChatRoomController.groovy | 3 + .../com/muwire/gui/MainFrameController.groovy | 2 + .../com/muwire/gui/ChatServerModel.groovy | 7 ++ .../views/com/muwire/gui/ChatRoomView.groovy | 4 + .../com/muwire/gui/ChatServerView.groovy | 9 +- .../views/com/muwire/gui/MainFrameView.groovy | 20 ++++ .../com/muwire/gui/ChatNotificator.groovy | 91 +++++++++++++++++++ 7 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 gui/src/main/groovy/com/muwire/gui/ChatNotificator.groovy diff --git a/gui/griffon-app/controllers/com/muwire/gui/ChatRoomController.groovy b/gui/griffon-app/controllers/com/muwire/gui/ChatRoomController.groovy index a60ff934..08119d16 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/ChatRoomController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/ChatRoomController.groovy @@ -71,6 +71,7 @@ class ChatRoomController { params['console'] = false params['host'] = model.host params['roomTabName'] = newRoom + params['chatNotificator'] = view.chatNotificator mvcGroup.parentGroup.createMVCGroup("chat-room", model.host.getHumanReadableName()+"-"+newRoom, params) } @@ -110,6 +111,7 @@ class ChatRoomController { params['privateChat'] = true params['host'] = model.host params['roomTabName'] = p.getHumanReadableName() + params['chatNotificator'] = view.chatNotificator mvcGroup.parentGroup.createMVCGroup("chat-room", groupId, params) } @@ -191,6 +193,7 @@ class ChatRoomController { runInsideUIAsync { view.roomTextArea.append(toDisplay) trimLines() + view.chatNotificator.onMessage(mvcGroup.mvcId) } } diff --git a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy index 9c4ce0cd..cb28df50 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy @@ -458,6 +458,7 @@ class MainFrameController { def params = [:] params['core'] = model.core params['host'] = model.core.me + params['chatNotificator'] = view.chatNotificator mvcGroup.createMVCGroup("chat-server","local-chat-server", params) } } @@ -489,6 +490,7 @@ class MainFrameController { def params = [:] params['core'] = model.core params['host'] = p + params['chatNotificator'] = view.chatNotificator mvcGroup.createMVCGroup("chat-server", p.getHumanReadableName(), params) } else mvcGroup.getChildrenGroups().get(p.getHumanReadableName()).model.connect() diff --git a/gui/griffon-app/models/com/muwire/gui/ChatServerModel.groovy b/gui/griffon-app/models/com/muwire/gui/ChatServerModel.groovy index 463c8c11..0e0ff32e 100644 --- a/gui/griffon-app/models/com/muwire/gui/ChatServerModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/ChatServerModel.groovy @@ -2,6 +2,8 @@ package com.muwire.gui import java.util.logging.Level +import javax.annotation.Nonnull + import com.muwire.core.Core import com.muwire.core.Persona import com.muwire.core.chat.ChatCommand @@ -13,6 +15,7 @@ import com.muwire.core.chat.ChatMessageEvent import com.muwire.core.chat.UIConnectChatEvent import griffon.core.artifact.GriffonModel +import griffon.inject.MVCMember import griffon.transform.Observable import groovy.util.logging.Log import griffon.metadata.ArtifactProviderFor @@ -20,6 +23,9 @@ import griffon.metadata.ArtifactProviderFor @Log @ArtifactProviderFor(GriffonModel) class ChatServerModel { + @MVCMember @Nonnull + ChatServerView view + Persona host Core core @@ -133,6 +139,7 @@ class ChatServerModel { params['privateChat'] = true params['host'] = host params['roomTabName'] = e.sender.getHumanReadableName() + params['chatNotificator'] = view.chatNotificator mvcGroup.createMVCGroup("chat-room",groupId, params) } diff --git a/gui/griffon-app/views/com/muwire/gui/ChatRoomView.groovy b/gui/griffon-app/views/com/muwire/gui/ChatRoomView.groovy index 34fa6923..7a8a5f13 100644 --- a/gui/griffon-app/views/com/muwire/gui/ChatRoomView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/ChatRoomView.groovy @@ -29,6 +29,8 @@ class ChatRoomView { @MVCMember @Nonnull ChatRoomController controller + ChatNotificator chatNotificator + def pane def parent def sayField @@ -92,6 +94,7 @@ class ChatRoomView { } SmartScroller smartScroller = new SmartScroller(textScrollPane) + pane.putClientProperty("mvcId", mvcGroup.mvcId) } void mvcGroupInit(Map args) { @@ -173,6 +176,7 @@ class ChatRoomView { int index = parent.indexOfComponent(pane) parent.removeTabAt(index) controller.leaveRoom() + chatNotificator.roomClosed(mvcGroup.mvcId) mvcGroup.destroy() } } \ No newline at end of file diff --git a/gui/griffon-app/views/com/muwire/gui/ChatServerView.groovy b/gui/griffon-app/views/com/muwire/gui/ChatServerView.groovy index 5cabecbd..92fd6541 100644 --- a/gui/griffon-app/views/com/muwire/gui/ChatServerView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/ChatServerView.groovy @@ -19,14 +19,17 @@ class ChatServerView { ChatServerModel model @MVCMember @Nonnull ChatServerController controller + + ChatNotificator chatNotificator def pane def parent + def childPane void initUI() { pane = builder.panel { borderLayout() - tabbedPane(id : model.host.getHumanReadableName()+"-chat-rooms", constraints : BorderLayout.CENTER) + childPane = tabbedPane(id : model.host.getHumanReadableName()+"-chat-rooms", constraints : BorderLayout.CENTER) panel(constraints : BorderLayout.SOUTH) { gridLayout(rows : 1, cols : 3) panel {} @@ -39,6 +42,9 @@ class ChatServerView { } } } + pane.putClientProperty("mvcId",mvcGroup.mvcId) + pane.putClientProperty("childPane", childPane) + childPane.addChangeListener({e -> chatNotificator.roomTabChanged(e.getSource())}) } void mvcGroupInit(Map args) { @@ -69,6 +75,7 @@ class ChatServerView { params['roomTabName'] = 'Console' params['console'] = true params['host'] = model.host + params['chatNotificator'] = chatNotificator mvcGroup.createMVCGroup("chat-room",model.host.getHumanReadableName()+"-"+ChatServer.CONSOLE, params) } diff --git a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy index 238eb6bd..6beda9fc 100644 --- a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy @@ -78,8 +78,10 @@ class MainFrameView { UISettings settings + ChatNotificator chatNotificator void initUI() { + chatNotificator = new ChatNotificator(application.getMvcGroupManager()) settings = application.context.get("ui-settings") int rowHeight = application.context.get("row-height") builder.with { @@ -522,6 +524,7 @@ class MainFrameView { mainFrame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { + chatNotificator.mainWindowDeactivated() if (application.getContext().get("tray-icon")) { if (settings.closeWarning) { runInsideUIAsync { @@ -535,6 +538,13 @@ class MainFrameView { } else { closeApplication() } + } + public void windowDeactivated(WindowEvent e) { + chatNotificator.mainWindowDeactivated() + } + public void windowActivated(WindowEvent e) { + if (!model.chatPaneButtonEnabled) + chatNotificator.mainWindowActivated() }}) // search field @@ -831,6 +841,10 @@ class MainFrameView { } }) + // chat tabs + def chatTabbedPane = builder.getVariable("chat-tabs") + chatTabbedPane.addChangeListener({e -> chatNotificator.serverTabChanged(e.getSource())}) + // show tree by default showSharedFilesTree.call() @@ -1033,6 +1047,7 @@ class MainFrameView { model.monitorPaneButtonEnabled = true model.trustPaneButtonEnabled = true model.chatPaneButtonEnabled = true + chatNotificator.mainWindowDeactivated() } def showDownloadsWindow = { @@ -1044,6 +1059,7 @@ class MainFrameView { model.monitorPaneButtonEnabled = true model.trustPaneButtonEnabled = true model.chatPaneButtonEnabled = true + chatNotificator.mainWindowDeactivated() } def showUploadsWindow = { @@ -1055,6 +1071,7 @@ class MainFrameView { model.monitorPaneButtonEnabled = true model.trustPaneButtonEnabled = true model.chatPaneButtonEnabled = true + chatNotificator.mainWindowDeactivated() } def showMonitorWindow = { @@ -1066,6 +1083,7 @@ class MainFrameView { model.monitorPaneButtonEnabled = false model.trustPaneButtonEnabled = true model.chatPaneButtonEnabled = true + chatNotificator.mainWindowDeactivated() } def showTrustWindow = { @@ -1077,6 +1095,7 @@ class MainFrameView { model.monitorPaneButtonEnabled = true model.trustPaneButtonEnabled = false model.chatPaneButtonEnabled = true + chatNotificator.mainWindowDeactivated() } def showChatWindow = { @@ -1088,6 +1107,7 @@ class MainFrameView { model.monitorPaneButtonEnabled = true model.trustPaneButtonEnabled = true model.chatPaneButtonEnabled = false + chatNotificator.mainWindowActivated() } def showSharedFilesTable = { diff --git a/gui/src/main/groovy/com/muwire/gui/ChatNotificator.groovy b/gui/src/main/groovy/com/muwire/gui/ChatNotificator.groovy new file mode 100644 index 00000000..4139237e --- /dev/null +++ b/gui/src/main/groovy/com/muwire/gui/ChatNotificator.groovy @@ -0,0 +1,91 @@ +package com.muwire.gui + +import java.awt.Taskbar +import java.awt.Taskbar.Feature + +import javax.swing.JPanel +import javax.swing.JTabbedPane + +import griffon.core.mvc.MVCGroupManager + +class ChatNotificator { + + private final MVCGroupManager groupManager + + private boolean chatInFocus + private String currentServerTab + private String currentRoomTab + + private final Map roomsWithMessages = new HashMap<>() + + ChatNotificator(MVCGroupManager groupManager) { + this.groupManager = groupManager + } + + void serverTabChanged(JTabbedPane source) { + JPanel panel = source.getSelectedComponent() + String mvcId = panel.getClientProperty("mvcId") + def group = groupManager.getGroups().get(mvcId) + JTabbedPane childPane = panel.getClientProperty("childPane") + JPanel roomPanel = childPane.getSelectedComponent() + + currentServerTab = mvcId + currentRoomTab = childPane.getSelectedComponent()?.getClientProperty("mvcId") + + if (currentRoomTab != null) { + roomsWithMessages.remove(currentRoomTab) + updateBadge() + } + } + + void roomTabChanged(JTabbedPane source) { + JPanel panel = source.getSelectedComponent() + currentRoomTab = panel.getClientProperty("mvcId") + roomsWithMessages.remove(currentRoomTab) + updateBadge() + } + + void roomClosed(String mvcId) { + roomsWithMessages.remove(mvcId) + updateBadge() + } + + void mainWindowDeactivated() { + chatInFocus = false + } + + void mainWindowActivated() { + chatInFocus = true + if (currentRoomTab != null) + roomsWithMessages.remove(currentRoomTab) + updateBadge() + } + + void onMessage(String roomId) { + if (roomId != currentRoomTab || !chatInFocus) { + Integer previous = roomsWithMessages[roomId] + if (previous == null) + roomsWithMessages[roomId] = 1 + else + roomsWithMessages[roomId] = previous + 1 + } + updateBadge() + } + + private void updateBadge() { + if (!Taskbar.isTaskbarSupported()) + return + def taskBar = Taskbar.getTaskbar() + if (!taskBar.isSupported(Feature.ICON_BADGE_NUMBER)) + return + if (roomsWithMessages.isEmpty()) + taskBar.setIconBadge("") + else { + int total = 0 + roomsWithMessages.values().each { + total += it + } + taskBar.setIconBadge(String.valueOf(total)) + } + } +}