Move various functions in QML code to new utils.js
This commit is contained in:
		| @@ -17,7 +17,6 @@ class RoomUpdated(Event): | ||||
|     display_name:    Optional[str]      = None | ||||
|     avatar_url:      Optional[str]      = None | ||||
|     topic:           Optional[str]      = None | ||||
|     last_event_date: Optional[datetime] = None | ||||
|  | ||||
|     inviter:    Optional[str]            = None | ||||
|     left_event: Optional[Dict[str, str]] = None | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import QtQuick 2.7 | ||||
| import "../Base" | ||||
| import "../utils.js" as Utils | ||||
|  | ||||
| Rectangle { | ||||
|     property var name: null | ||||
| @@ -7,21 +8,6 @@ Rectangle { | ||||
|     property int dimension: HStyle.avatar.size | ||||
|     property bool hidden: false | ||||
|  | ||||
|     function stripUserId(user_id) { | ||||
|         return user_id.substring(1)  // Remove leading @ | ||||
|     } | ||||
|     function stripRoomName(name) { | ||||
|         return name[0] == "#" ? name.substring(1) : name | ||||
|     } | ||||
|  | ||||
|     function hueFromName(name) { | ||||
|         var hue = 0 | ||||
|         for (var i = 0; i < name.length; i++) { | ||||
|             hue += name.charCodeAt(i) * 99 | ||||
|         } | ||||
|         return hue % 360 / 360 | ||||
|     } | ||||
|  | ||||
|     width: dimension | ||||
|     height: hidden ? 1 : dimension | ||||
|     implicitWidth: dimension | ||||
| @@ -29,14 +15,7 @@ Rectangle { | ||||
|  | ||||
|     opacity: hidden ? 0 : 1 | ||||
|  | ||||
|     color: name ? | ||||
|            Qt.hsla( | ||||
|                hueFromName(name), | ||||
|                HStyle.avatar.background.saturation, | ||||
|                HStyle.avatar.background.lightness, | ||||
|                HStyle.avatar.background.alpha | ||||
|            ) : | ||||
|            HStyle.avatar.background.unknown | ||||
|     color: name ? Utils.avatarHue(name) : HStyle.avatar.background.unknown | ||||
|  | ||||
|     HLabel { | ||||
|         z: 1 | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import QtQuick 2.7 | ||||
| import QtQuick.Layouts 1.3 | ||||
| import "../Base" | ||||
| import "../utils.js" as Utils | ||||
|  | ||||
| HRectangle { | ||||
|     property var displayName: "" | ||||
| @@ -22,7 +23,7 @@ HRectangle { | ||||
|  | ||||
|         HAvatar { | ||||
|             id: avatar | ||||
|             name: stripRoomName(displayName) || qsTr("Empty room") | ||||
|             name: Utils.stripRoomName(displayName) | ||||
|             dimension: roomHeader.height | ||||
|             Layout.alignment: Qt.AlignTop | ||||
|         } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import QtQuick 2.7 | ||||
| import QtQuick.Layouts 1.3 | ||||
| import "../../Base" | ||||
| import "../utils.js" as Utils | ||||
|  | ||||
| MouseArea { | ||||
|     id: memberDelegate | ||||
| @@ -15,7 +16,7 @@ MouseArea { | ||||
|  | ||||
|         HAvatar { | ||||
|             id: memberAvatar | ||||
|             name: member.displayName || stripUserId(member.userId) | ||||
|             name: member.displayName || Utils.stripUserId(member.userId) | ||||
|         } | ||||
|  | ||||
|         HColumnLayout { | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import QtQuick 2.7 | ||||
| import QtQuick.Layouts 1.3 | ||||
| import "../Base" | ||||
| import "../utils.js" as Utils | ||||
|  | ||||
| HRectangle { | ||||
|     function setFocus() { textArea.forceActiveFocus() } | ||||
| @@ -18,7 +19,8 @@ HRectangle { | ||||
|  | ||||
|         HAvatar { | ||||
|             id: avatar | ||||
|             name: chatPage.sender.displayName || stripUserId(chatPage.userId) | ||||
|             name: chatPage.sender.displayName || | ||||
|                   Utils.stripUserId(chatPage.userId) | ||||
|             dimension: root.Layout.minimumHeight | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,23 +1,17 @@ | ||||
| import QtQuick 2.7 | ||||
| import QtQuick.Layouts 1.3 | ||||
| import "../../Base" | ||||
| import "../../utils.js" as Utils | ||||
|  | ||||
| Row { | ||||
|     id: messageContent | ||||
|     spacing: standardSpacing / 2 | ||||
|     layoutDirection: isOwn ? Qt.RightToLeft : Qt.LeftToRight | ||||
|  | ||||
|     function textHueForName(name) { // TODO: move | ||||
|         return Qt.hsla(avatar.hueFromName(name), | ||||
|                        HStyle.displayName.saturation, | ||||
|                        HStyle.displayName.lightness, | ||||
|                        1) | ||||
|     } | ||||
|  | ||||
|     HAvatar { | ||||
|         id: avatar | ||||
|         hidden: combine | ||||
|         name: senderInfo.displayName || stripUserId(model.senderId) | ||||
|         name: senderInfo.displayName || Utils.stripUserId(model.senderId) | ||||
|         dimension: model.showNameLine ? 48 : 28 | ||||
|     } | ||||
|  | ||||
| @@ -47,7 +41,7 @@ Row { | ||||
|  | ||||
|                 id: nameLabel | ||||
|                 text: senderInfo.displayName || model.senderId | ||||
|                 color: textHueForName(avatar.name) | ||||
|                 color: Utils.nameHue(avatar.name) | ||||
|                 elide: Text.ElideRight | ||||
|                 maximumLineCount: 1 | ||||
|                 horizontalAlignment: isOwn ? Text.AlignRight : Text.AlignLeft | ||||
| @@ -58,56 +52,20 @@ Row { | ||||
|             } | ||||
|  | ||||
|             HRichLabel { | ||||
|                 function escapeHtml(text) {  // TODO: move this | ||||
|                     return text.replace("&", "&") | ||||
|                                .replace("<", "<") | ||||
|                                .replace(">", ">") | ||||
|                                .replace('"', """) | ||||
|                                .replace("'", "'") | ||||
|                 } | ||||
|  | ||||
|                 function translate(text) { | ||||
|                     if (model.translatable == false) { return text } | ||||
|  | ||||
|                     text = text.replace( | ||||
|                         "%S", | ||||
|                         "<font color='" + nameLabel.color + "'>" + | ||||
|                         escapeHtml(senderInfo.displayName || model.senderId) + | ||||
|                         "</font>" | ||||
|                     ) | ||||
|  | ||||
|                     var name = models.users.getUser( | ||||
|                         chatPage.userId, model.targetUserId | ||||
|                     ).displayName | ||||
|                     var sid = avatar.stripUserId(model.targetUserId || "") | ||||
|  | ||||
|                     text = text.replace( | ||||
|                         "%T", | ||||
|                         "<font color='" + textHueForName(name || sid) + "'>" + | ||||
|                         escapeHtml(name || model.targetUserId) + | ||||
|                         "</font>" | ||||
|                     ) | ||||
|  | ||||
|                     text = qsTr(text) | ||||
|                     if (model.translatable == true) { return text } | ||||
|  | ||||
|                     // Else, model.translatable should be an array of args | ||||
|                     for (var i = 0; model.translatable.length; i++) { | ||||
|                         text = text.arg(model.translatable[i]) | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 width: parent.width | ||||
|  | ||||
|                 id: contentLabel | ||||
|                 text: translate(model.content) + | ||||
|                 text: Utils.translatedEventContent(model) + | ||||
|                       // time | ||||
|                       "  <font size=" + HStyle.fontSize.small + | ||||
|                       "px color=" + HStyle.chat.message.date + ">" + | ||||
|                       Qt.formatDateTime(model.date, "hh:mm:ss") + | ||||
|                       "</font>" + | ||||
|                       // local echo icon | ||||
|                       (model.isLocalEcho ? | ||||
|                        " <font size=" + HStyle.fontSize.small + | ||||
|                        "px>⏳</font>" : "") | ||||
|  | ||||
|                 color: HStyle.chat.message.body | ||||
|                 wrapMode: Text.Wrap | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| function onRoomUpdated(user_id, category, room_id, display_name, avatar_url, | ||||
|                        topic, last_event_date, inviter, left_event) { | ||||
|                        topic, inviter, left_event) { | ||||
|  | ||||
|     models.roomCategories.upsert({"userId": user_id, "name": category}, { | ||||
|         "userId": user_id, | ||||
| @@ -39,7 +39,6 @@ function onRoomUpdated(user_id, category, room_id, display_name, avatar_url, | ||||
|         "displayName":   display_name, | ||||
|         "avatarUrl":     avatar_url, | ||||
|         "topic":         topic, | ||||
|         "lastEventDate": last_event_date, | ||||
|         "inviter":       inviter, | ||||
|         "leftEvent":     left_event | ||||
|     }) | ||||
| @@ -72,10 +71,10 @@ function onTimelineEventReceived( | ||||
|         "date":         date, | ||||
|         "content":      content, | ||||
|         "contentType":  content_type, | ||||
|         "isLocalEcho":  is_local_echo, | ||||
|         "showNameLine": show_name_line, | ||||
|         "translatable": translatable, | ||||
|         "targetUserId": target_user_id, | ||||
|         "isLocalEcho":  is_local_echo, | ||||
|         "targetUserId": target_user_id || "", | ||||
|     } | ||||
|  | ||||
|     // Replace any matching local echo | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import QtQuick 2.7 | ||||
| import QtQuick.Layouts 1.3 | ||||
| import "../Base" | ||||
| import "../utils.js" as Utils | ||||
|  | ||||
| Column { | ||||
|     id: accountDelegate | ||||
| @@ -20,7 +21,7 @@ Column { | ||||
|  | ||||
|         HAvatar { | ||||
|             id: avatar | ||||
|             name: user.displayName || stripUserId(user.userId) | ||||
|             name: user.displayName || Utils.stripUserId(user.userId) | ||||
|         } | ||||
|  | ||||
|         HColumnLayout { | ||||
|   | ||||
| @@ -1,14 +1,15 @@ | ||||
| import QtQuick 2.7 | ||||
| import QtQuick.Layouts 1.3 | ||||
| import "../Base" | ||||
| import "utils.js" as SidePaneJS | ||||
| import "../utils.js" as Utils | ||||
|  | ||||
| MouseArea { | ||||
|     id: roomDelegate | ||||
|     width: roomList.width | ||||
|     height: childrenRect.height | ||||
|  | ||||
|     onClicked: pageStack.showRoom(roomList.userId, roomList.category, roomId) | ||||
|     onClicked: | ||||
|         pageStack.showRoom(roomList.userId, roomList.category, model.roomId) | ||||
|  | ||||
|     HRowLayout { | ||||
|         width: parent.width | ||||
| @@ -16,7 +17,7 @@ MouseArea { | ||||
|  | ||||
|         HAvatar { | ||||
|             id: roomAvatar | ||||
|             name: stripRoomName(displayName) || qsTr("Empty room") | ||||
|             name: Utils.stripRoomName(model.displayName) | ||||
|         } | ||||
|  | ||||
|         HColumnLayout { | ||||
| @@ -26,8 +27,8 @@ MouseArea { | ||||
|  | ||||
|             HLabel { | ||||
|                 id: roomLabel | ||||
|                 text: displayName ? displayName : "<i>Empty room</i>" | ||||
|                 textFormat: Text.StyledText | ||||
|                 text: model.displayName || "<i>Empty room</i>" | ||||
|                 textFormat: model.displayName? Text.PlainText : Text.StyledText | ||||
|                 elide: Text.ElideRight | ||||
|                 maximumLineCount: 1 | ||||
|                 verticalAlignment: Qt.AlignVCenter | ||||
| @@ -35,27 +36,18 @@ MouseArea { | ||||
|                 Layout.maximumWidth: parent.width | ||||
|             } | ||||
|  | ||||
|             //HLabel { | ||||
|                 //function getText() { | ||||
|                     //return SidePaneJS.getLastRoomEventText( | ||||
|                         //roomId, roomList.userId | ||||
|                     //) | ||||
|                 //} | ||||
|             HLabel { | ||||
|                 id: subtitleLabel | ||||
|                 visible: Boolean(text) | ||||
|                 //text: models.timelines.getWhere({"roomId": model.roomId}, 1)[0].content | ||||
|                 textFormat: Text.StyledText | ||||
|  | ||||
|                 //property var lastEvTime: lastEventDateTime | ||||
|                 //onLastEvTimeChanged: subtitleLabel.text = getText() | ||||
|                 font.pixelSize: HStyle.fontSize.small | ||||
|                 elide: Text.ElideRight | ||||
|                 maximumLineCount: 1 | ||||
|  | ||||
|                 //id: subtitleLabel | ||||
|                 //visible: text !== "" | ||||
|                 //text: getText() | ||||
|                 //textFormat: Text.StyledText | ||||
|  | ||||
|                 //font.pixelSize: HStyle.fontSize.small | ||||
|                 //elide: Text.ElideRight | ||||
|                 //maximumLineCount: 1 | ||||
|  | ||||
|                 //Layout.maximumWidth: parent.width | ||||
|             //} | ||||
|                 Layout.maximumWidth: parent.width | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										87
									
								
								src/qml/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/qml/utils.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| function stripUserId(user_id) { | ||||
|     // Remove leading @ | ||||
|     return user_id.substring(1) | ||||
| } | ||||
|  | ||||
|  | ||||
| function stripRoomName(name) { | ||||
|     // Remove leading # (aliases) | ||||
|     return name[0] == "#" ? name.substring(1) : name | ||||
| } | ||||
|  | ||||
|  | ||||
| function hueFrom(string) { | ||||
|     // Calculate and return a unique hue between 0 and 1 for the string | ||||
|     var hue = 0 | ||||
|     for (var i = 0; i < string.length; i++) { | ||||
|         hue += string.charCodeAt(i) * 99 | ||||
|     } | ||||
|     return hue % 360 / 360 | ||||
| } | ||||
|  | ||||
|  | ||||
| function avatarHue(name) { | ||||
|    return Qt.hsla( | ||||
|        hueFrom(name), | ||||
|        HStyle.avatar.background.saturation, | ||||
|        HStyle.avatar.background.lightness, | ||||
|        HStyle.avatar.background.alpha | ||||
|    ) | ||||
| } | ||||
|  | ||||
|  | ||||
| function nameHue(name) { | ||||
|     return Qt.hsla( | ||||
|         hueFrom(name), | ||||
|         HStyle.displayName.saturation, | ||||
|         HStyle.displayName.lightness, | ||||
|         1 | ||||
|     ) | ||||
| } | ||||
|  | ||||
|  | ||||
| function escapeHtml(string) { | ||||
|     // Replace special HTML characters by encoded alternatives | ||||
|     return string.replace("&", "&") | ||||
|                  .replace("<", "<") | ||||
|                  .replace(">", ">") | ||||
|                  .replace('"', """) | ||||
|                  .replace("'", "'") | ||||
| } | ||||
|  | ||||
|  | ||||
| function translatedEventContent(ev) { | ||||
|     // ev: models.timelines item | ||||
|     if (ev.translatable == false) { return ev.content } | ||||
|  | ||||
|     // %S → sender display name | ||||
|     var name = models.users.getUser(ev.senderId).displayName | ||||
|     var text = ev.content.replace( | ||||
|         "%S", | ||||
|         "<font color='" + nameHue(name || stripUserId(ev.senderId)) + "'>" + | ||||
|         escapeHtml(name || ev.senderId) + | ||||
|         "</font>" | ||||
|     ) | ||||
|  | ||||
|     // %T → target (event state_key) display name | ||||
|     if (ev.targetUserId) { | ||||
|         var target_name = models.users.getUser(ev.targetUserId).displayName | ||||
|         text = text.replace( | ||||
|             "%T", | ||||
|             "<font color='" + | ||||
|             nameHue(target_name || stripUserId(ev.targetUserId)) + | ||||
|             "'>" + | ||||
|             escapeHtml(target_name || ev.targetUserId) + | ||||
|             "</font>" | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     text = qsTr(text) | ||||
|     if (model.translatable == true) { return text } | ||||
|  | ||||
|     // Else, model.translatable should be an array of args | ||||
|     for (var i = 0; model.translatable.length; i++) { | ||||
|         text = text.arg(model.translatable[i]) | ||||
|     } | ||||
|     return text | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	