mirror of https://github.com/zlatinb/muwire
Avatars in chat, multi-line paste support
parent
9b931dbdb4
commit
27b734bc40
1
TODO.md
1
TODO.md
|
@ -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 |
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue