Avatars in chat, multi-line paste support

dbus-notify
Zlatin Balevsky 2022-06-08 17:10:03 +01:00
parent 9b931dbdb4
commit 27b734bc40
No known key found for this signature in database
GPG Key ID: A72832072D525E41
6 changed files with 121 additions and 21 deletions

View File

@ -38,7 +38,6 @@
|Downloads queue with priorities | N/A | Core, GUI | Medium |
|Remote queuing of uploads | N/A | Core, Network, GUI | Medium |
|Incomplete file handling | 2 | Core, Portable | Low |
|Chat - break up lines on CR/LF | N/A | GUI | Low |
|Chat - enforce # in room names | N/A | GUI | Low |
|Chat - jump from notification window to room | N/A | GUI | Optional |
|Chat - emoji support | 113 | GUI | Low |

View File

@ -61,14 +61,7 @@ class ChatRoomController {
long now = System.currentTimeMillis()
if (command.action == ChatAction.SAY && command.payload.length() > 0) {
String header = DataHelper.formatTime(now) + " <" + model.core.me.getHumanReadableName() + ">"
StyledDocument sd = view.roomTextArea.getStyledDocument()
sd.insertString(sd.getEndPosition().getOffset() - 1, header, sd.getStyle("italic"))
sd.insertString(sd.getEndPosition().getOffset() - 1, " ", sd.getStyle("regular"))
sd.insertString(sd.getEndPosition().getOffset() - 1, command.payload, sd.getStyle("regular"))
sd.insertString(sd.getEndPosition().getOffset() - 1, "\n", sd.getStyle("regular"))
trimLines()
view.appendSay(command.payload, model.buildChatPOP(model.core.me), now)
}
if (command.action == ChatAction.JOIN && model.console) {
@ -208,8 +201,7 @@ class ChatRoomController {
private void processSay(ChatMessageEvent e, String text) {
runInsideUIAsync {
view.appendSay(text, e.sender, e.timestamp)
trimLines()
view.appendSay(text, model.buildChatPOP(e.sender), e.timestamp)
if (!model.console)
view.chatNotificator.onMessage(mvcGroup.mvcId)
}
@ -266,7 +258,7 @@ class ChatRoomController {
}
}
private void trimLines() {
void trimLines() {
if (model.settings.maxChatLines < 0)
return
while(view.getLineCount() > model.settings.maxChatLines)

View File

@ -1,6 +1,9 @@
package com.muwire.gui
import com.muwire.core.trust.TrustLevel
import com.muwire.gui.chat.ChatEntry
import com.muwire.gui.chat.ChatTextField
import com.muwire.gui.contacts.POPLabel
import com.muwire.gui.profile.PersonaOrProfile
import com.muwire.gui.profile.PersonaOrProfileCellRenderer
import com.muwire.gui.profile.PersonaOrProfileComparator
@ -8,6 +11,11 @@ import griffon.core.GriffonApplication
import griffon.core.artifact.GriffonView
import javax.inject.Inject
import javax.swing.BorderFactory
import javax.swing.JLabel
import javax.swing.JScrollPane
import javax.swing.border.Border
import java.text.SimpleDateFormat
import static com.muwire.gui.Translator.trans
import griffon.inject.MVCMember
@ -52,15 +60,21 @@ class ChatRoomView {
def pane
def parent
def sayField
ChatTextField sayField
JTextPane roomTextArea
def textScrollPane
def membersTable
def lastMembersTableSortEvent
UISettings settings
private static final SimpleDateFormat SDF = new SimpleDateFormat("dd/MM hh:mm:ss")
void initUI() {
settings = application.context.get("ui-settings")
int rowHeight = application.context.get("row-height")
def parentModel = mvcGroup.parentGroup.model
sayField = new ChatTextField()
if (model.console || model.privateChat) {
pane = builder.panel {
borderLayout()
@ -73,7 +87,9 @@ class ChatRoomView {
panel(constraints : BorderLayout.SOUTH) {
borderLayout()
label(text : trans("SAY_SOMETHING_HERE") + ": ", constraints : BorderLayout.WEST)
sayField = textField(enabled : bind {parentModel.sayActionEnabled}, actionPerformed : {controller.say()}, constraints : BorderLayout.CENTER)
scrollPane(verticalScrollBarPolicy: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, constraints: BorderLayout.CENTER) {
widget(sayField, enabled: bind { parentModel.sayActionEnabled }, actionPerformed: { controller.say() })
}
}
}
} else {
@ -105,7 +121,9 @@ class ChatRoomView {
panel(constraints : BorderLayout.SOUTH) {
borderLayout()
label(text : trans("SAY_SOMETHING_HERE") + ": ", constraints : BorderLayout.WEST)
sayField = textField(enabled : bind {parentModel.sayActionEnabled}, actionPerformed : {controller.say()}, constraints : BorderLayout.CENTER)
scrollPane(verticalScrollBarPolicy: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, constraints: BorderLayout.CENTER) {
widget(sayField, enabled: bind { parentModel.sayActionEnabled }, actionPerformed: { controller.say() })
}
}
}
@ -222,12 +240,26 @@ class ChatRoomView {
doc.insertString(doc.getEndPosition().getOffset() - 1, gray, doc.getStyle("gray"))
}
void appendSay(String text, Persona sender, long timestamp) {
void appendSay(String text, PersonaOrProfile sender, long timestamp) {
StyledDocument doc = roomTextArea.getStyledDocument()
String header = DataHelper.formatTime(timestamp) + " <" + sender.getHumanReadableName() + "> "
doc.insertString(doc.getEndPosition().getOffset() - 1, header, doc.getStyle("italic"))
doc.insertString(doc.getEndPosition().getOffset() - 1, text, doc.getStyle("regular"))
def label = new DateLabel(timestamp)
def style = doc.addStyle("newStyle", null)
StyleConstants.setComponent(style, label)
doc.insertString(doc.getEndPosition().getOffset() - 1, " ", style)
Border border = BorderFactory.createEmptyBorder(0, 5, 0, 5)
label = new POPLabel(sender, settings, border, JLabel.TOP)
label.setAlignmentY(0f)
style = doc.addStyle("newStyle", null)
StyleConstants.setComponent(style, label)
doc.insertString(doc.getEndPosition().getOffset() - 1, " ", style)
def textField = new ChatEntry("$text")
style = doc.addStyle("newStyle", null)
StyleConstants.setComponent(style, textField)
doc.insertString(doc.getEndPosition().getOffset() - 1, " ", style)
doc.insertString(doc.getEndPosition().getOffset() - 1, "\n", doc.getStyle("regular"))
controller.trimLines()
}
int getLineCount() {
@ -240,4 +272,12 @@ class ChatRoomView {
Element element = doc.getParagraphElement(0)
doc.remove(0, element.getEndOffset())
}
private static class DateLabel extends JLabel {
DateLabel(long now) {
setAlignmentY(0f)
String text = SDF.format(new Date(now))
setText(text)
}
}
}

View File

@ -0,0 +1,27 @@
package com.muwire.gui.chat
import javax.swing.JTextArea
import javax.swing.JTextField
class ChatEntry extends JTextArea {
ChatEntry(String text) {
setEditable(false)
setLineWrap(true)
setWrapStyleWord(true)
setColumns(countRows(text))
setText(text)
setAlignmentY(0f)
}
private static int countRows(String text) {
int rv = 0
char newLine = "\n".toCharacter()
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i)
if (c == newLine)
rv++
}
rv
}
}

View File

@ -0,0 +1,34 @@
package com.muwire.gui.chat
import javax.swing.JTextField
import javax.swing.text.AttributeSet
import javax.swing.text.BadLocationException
import javax.swing.text.Document
import javax.swing.text.PlainDocument
class ChatTextField extends JTextField {
ChatTextField() {
setEditable(true)
}
protected Document createDefaultModel() {
return new ChatDocument()
}
private static class ChatDocument extends PlainDocument {
@Override
void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
println "inserting string $str"
getDocumentProperties().put("filterNewlines", false)
super.insertString(offs, str, a)
}
@Override
String getText(int offset, int length) throws BadLocationException {
String rv = super.getText(offset, length)
println "getting string $rv"
return rv
}
}
}

View File

@ -15,12 +15,20 @@ class POPLabel extends JLabel {
private final UISettings settings
POPLabel(PersonaOrProfile personaOrProfile, UISettings settings) {
this(personaOrProfile, settings,
BorderFactory.createEmptyBorder(2, 2, 2, 2),
JLabel.CENTER)
}
POPLabel(PersonaOrProfile personaOrProfile, UISettings settings,
Border border, int verticalAllignment) {
super()
setVerticalAlignment(verticalAllignment)
this.personaOrProfile = personaOrProfile
this.settings = settings
Border border = BorderFactory.createEmptyBorder(2, 2, 2, 2)
setBorder(border)
if (border != null)
setBorder(border)
MWProfileHeader header = personaOrProfile.getHeader()
if (settings.personaRendererAvatars) {