Improve account status msg field & add history
- Up to 5 previously set status are now shown under the field for quick access; the history is shared between accounts - When focusing the field, the text gets auto-selected since most of the time we want to set a totally different status, not edit the current one - Typing in the field will autosuggest any matching history entry - Keyboard focus now skips the "apply" button, since we can just hit enter in the field
This commit is contained in:
		| @@ -8,7 +8,7 @@ import Clipboard 0.1 | ||||
| import "../Base" | ||||
|  | ||||
| HMenu { | ||||
|     id: accountMenu | ||||
|     id: root | ||||
|  | ||||
|     property string userId | ||||
|     property string presence | ||||
| @@ -20,32 +20,69 @@ HMenu { | ||||
|         py.callClientCoro(userId, "set_presence", [presence, statusMsg]) | ||||
|     } | ||||
|  | ||||
|     onOpened: statusText.forceActiveFocus() | ||||
|     function statusFieldApply(newStatus=null) { | ||||
|         if (newStatus === null) newStatus = statusField.editText.trim() | ||||
|  | ||||
|         if (newStatus) { | ||||
|             const existing = statusRepeater.items.indexOf(newStatus) | ||||
|             if (existing !== -1) statusRepeater.items.splice(existing, 1) | ||||
|  | ||||
|             statusRepeater.items.unshift(newStatus) | ||||
|             statusRepeater.items.length = Math.min(statusRepeater.count, 5) | ||||
|             statusRepeater.itemsChanged() | ||||
|             window.saveState(statusRepeater) | ||||
|         } | ||||
|  | ||||
|         setPresence(presence, newStatus) | ||||
|         close() | ||||
|     } | ||||
|  | ||||
|     onOpened: statusField.forceActiveFocus() | ||||
|  | ||||
|     HLabeledItem { | ||||
|         id: statusMsgLabel | ||||
|         enabled: presence && presence !== "offline" | ||||
|         width: parent.width | ||||
|         height: visible ? implicitHeight : 0 | ||||
|  | ||||
|         label.text: qsTr("Status message:") | ||||
|         label.horizontalAlignment: Qt.AlignHCenter | ||||
|  | ||||
|         Keys.onDownPressed: onlineButton.forceActiveFocus() | ||||
|         label.leftPadding: theme.spacing | ||||
|         label.rightPadding: label.leftPadding | ||||
|         label.topPadding: theme.spacing / 2 | ||||
|         label.bottomPadding: label.topPadding | ||||
|  | ||||
|         HRowLayout { | ||||
|             width: parent.width | ||||
|  | ||||
|             HTextField { | ||||
|                 id: statusText | ||||
|                 maximumLength: 255 | ||||
|                 horizontalAlignment: Qt.AlignHCenter | ||||
|                 onAccepted: { | ||||
|                     setPresence(presence, statusText.text) | ||||
|                     accountMenu.close() | ||||
|                 } | ||||
|             HComboBox { | ||||
|                 // We use a ComboBox disguised as a field for the | ||||
|                 // autosuggestion-as-we-type feature | ||||
|  | ||||
|                 defaultText: statusMsg | ||||
|                 placeholderText: presence ? "" : "Unsupported server" | ||||
|                 id: statusField | ||||
|                 editable: true | ||||
|                 indicator: null | ||||
|                 popup: null | ||||
|                 model: statusRepeater.model | ||||
|                 currentIndex: statusRepeater.items.indexOf( | ||||
|                     root.currentIndex !== -1 && | ||||
|                     root.itemAt(root.currentIndex).isStatus ? | ||||
|                     root.itemAt(root.currentIndex).text : | ||||
|                     root.statusMsg | ||||
|                 ) | ||||
|  | ||||
|                 field.placeholderText: presence ? "" : "Unsupported server" | ||||
|                 field.maximumLength: 255 | ||||
|  | ||||
|                 onAccepted: root.statusFieldApply() | ||||
|                 onActiveFocusChanged: if (activeFocus) field.selectAll() | ||||
|  | ||||
|                 Keys.onBacktabPressed: event => Keys.upPressed(event) | ||||
|                 Keys.onTabPressed: event => Keys.downPressed(event) | ||||
|  | ||||
|                 Keys.onUpPressed: signOutItem.forceActiveFocus() | ||||
|                 Keys.onDownPressed: | ||||
|                     (statusRepeater.itemAt(0) || onlineItem).forceActiveFocus() | ||||
|  | ||||
|                 Layout.fillWidth: true | ||||
|             } | ||||
| @@ -56,26 +93,52 @@ HMenu { | ||||
|  | ||||
|                 icon.name: "apply" | ||||
|                 icon.color: theme.colors.positiveBackground | ||||
|                 onClicked: { | ||||
|                     setPresence(presence, statusText.text) | ||||
|                     accountMenu.close() | ||||
|                 } | ||||
|                 onClicked: root.statusFieldApply() | ||||
|  | ||||
|                 Layout.fillHeight: true | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     HMenuSeparator { } | ||||
|     HMenuSeparator {} | ||||
|  | ||||
|     Repeater { | ||||
|         id: statusRepeater | ||||
|  | ||||
|         // Separate property instead of setting model directly so that we can | ||||
|         // manipulate this as a JS list, not a QQmlModel | ||||
|         property var items: window.getState(this, "items", []) | ||||
|  | ||||
|         readonly property string saveName: "lastStatus" | ||||
|         readonly property string saveId: "ALL" | ||||
|         readonly property var saveProperties: ["items"] | ||||
|  | ||||
|         model: items | ||||
|  | ||||
|         delegate: HMenuItem { | ||||
|             readonly property bool isStatus: true | ||||
|  | ||||
|             icon.name: "previously-set-status" | ||||
|             text: modelData | ||||
|             onTriggered: root.statusFieldApply(text) | ||||
|  | ||||
|             Keys.onBacktabPressed: event => Keys.upPressed(event) | ||||
|  | ||||
|             Keys.onUpPressed: event => { | ||||
|                 event.accepted = index === 0 | ||||
|                 if (event.accepted) statusField.forceActiveFocus() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     HMenuSeparator { visible: statusRepeater.count > 0 } | ||||
|  | ||||
|     HMenuItem { | ||||
|         id: onlineButton | ||||
|         id: onlineItem | ||||
|         icon.name: "presence-online" | ||||
|         icon.color: theme.controls.presence.online | ||||
|         text: qsTr("Online") | ||||
|         onTriggered: setPresence("online") | ||||
|  | ||||
|         Keys.onUpPressed: statusText.forceActiveFocus() | ||||
|     } | ||||
|  | ||||
|     HMenuItem { | ||||
| @@ -133,11 +196,14 @@ HMenu { | ||||
|     } | ||||
|  | ||||
|     HMenuItemPopupSpawner { | ||||
|         id: signOutItem | ||||
|         icon.name: "sign-out" | ||||
|         icon.color: theme.colors.negativeBackground | ||||
|         text: qsTr("Sign out") | ||||
|  | ||||
|         popup: "Popups/SignOutPopup.qml" | ||||
|         properties: { "userId": userId } | ||||
|  | ||||
|         Keys.onDownPressed: statusField.forceActiveFocus() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -51,6 +51,9 @@ ApplicationWindow { | ||||
|     } | ||||
|  | ||||
|     function saveState(obj) { | ||||
|         // obj should have these properties: saveName (str), | ||||
|         // saveId (str, default "ALL"), and saveProperties (array of str) | ||||
|  | ||||
|         if (! obj.saveName || ! obj.saveProperties || | ||||
|             obj.saveProperties.length < 1) return | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								src/icons/thin/previously-set-status.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/icons/thin/previously-set-status.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> | ||||
|     <path d="m24 12c0 6.627-5.373 12-12 12s-12-5.373-12-12h2c0 5.514 4.486 10 10 10s10-4.486 10-10-4.486-10-10-10c-2.777 0-5.287 1.141-7.099 2.977l2.061 2.061-6.962 1.354 1.305-7.013 2.179 2.18c2.172-2.196 5.182-3.559 8.516-3.559 6.627 0 12 5.373 12 12zm-13-6v8h7v-2h-5v-6z"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 368 B | 
		Reference in New Issue
	
	Block a user
	