Changeset View
Changeset View
Standalone View
Standalone View
smsapp/qml/ConversationDisplay.qml
Show All 32 Lines | 32 | readonly property QtObject person: PersonData { | |||
---|---|---|---|---|---|
33 | id: person | 33 | id: person | ||
34 | } | 34 | } | ||
35 | property QtObject device | 35 | property QtObject device | ||
36 | property string conversationId | 36 | property string conversationId | ||
37 | 37 | | |||
38 | property string phoneNumber | 38 | property string phoneNumber | ||
39 | title: person.person && person.person.name ? person.person.name : phoneNumber | 39 | title: person.person && person.person.name ? person.person.name : phoneNumber | ||
40 | 40 | | |||
41 | /** | ||||
42 | * Build a chat message which is representative of all chat messages | ||||
43 | * | ||||
44 | * In other words, one which I can use to get a reasonable height guess | ||||
45 | */ | ||||
46 | ChatMessage { | ||||
47 | id: genericMessage | ||||
48 | messageBody: "Generic Message Body" | ||||
49 | dateTime: new Date('2000-0-0') | ||||
50 | visible: false | ||||
51 | enabled: false | ||||
52 | } | ||||
53 | | ||||
41 | ListView { | 54 | ListView { | ||
55 | id: viewport | ||||
42 | model: QSortFilterProxyModel { | 56 | model: QSortFilterProxyModel { | ||
43 | id: model | 57 | id: model | ||
44 | sortOrder: Qt.AscendingOrder | 58 | sortOrder: Qt.AscendingOrder | ||
45 | sortRole: ConversationModel.DateRole | 59 | sortRole: ConversationModel.DateRole | ||
46 | sourceModel: ConversationModel { | 60 | sourceModel: ConversationModel { | ||
47 | deviceId: device.id() | 61 | deviceId: device.id() | ||
48 | threadId: page.conversationId | 62 | threadId: page.conversationId | ||
49 | } | 63 | } | ||
50 | } | 64 | } | ||
51 | 65 | | |||
52 | spacing: Kirigami.Units.largeSpacing | 66 | spacing: Kirigami.Units.largeSpacing | ||
53 | 67 | | |||
54 | delegate: ChatMessage { | 68 | delegate: ChatMessage { | ||
55 | messageBody: model.display | 69 | messageBody: model.display | ||
56 | sentByMe: model.fromMe | 70 | sentByMe: model.fromMe | ||
57 | dateTime: new Date(model.date) | 71 | dateTime: new Date(model.date) | ||
72 | | ||||
73 | ListView.onAdd: { | ||||
74 | if (index == viewport.count - 1) | ||||
75 | // This message is being inserted at the newest position | ||||
76 | // We want to scroll to show it if the user is "almost" looking at it | ||||
77 | | ||||
78 | // Define some fudge area. If the message is being drawn offscreen but within | ||||
79 | // this distance, we move to show it anyway. | ||||
80 | // Selected to be genericMessage.height because that value scales for different | ||||
81 | // font sizes / DPI / etc. -- Better ideas are welcome! | ||||
82 | // Double the value works nicely | ||||
83 | var offscreenFudge = 2 * genericMessage.height | ||||
84 | | ||||
85 | var viewportYBottom = viewport.contentY + viewport.height | ||||
86 | | ||||
87 | if (y < viewportYBottom + genericMessage.height) { | ||||
88 | viewport.currentIndex = index | ||||
89 | } | ||||
58 | } | 90 | } | ||
91 | } | ||||
92 | | ||||
93 | onMovementEnded: { | ||||
94 | // Unset the highlightRangeMode if it was set previously | ||||
95 | highlightRangeMode = ListView.ApplyRange | ||||
96 | highlightMoveDuration: -1 // "Re-enable" the highlight animation | ||||
59 | 97 | | |||
60 | // Set the view to start at the bottom of the page and track new elements if it was not manually scrolled up | 98 | if (atYBeginning) { | ||
61 | currentIndex: atYEnd ? | 99 | // "Lock" the view to the message currently at the beginning of the view | ||
62 | count - 1 : | 100 | // This prevents the view from snapping to the top of the messages we are about to request | ||
63 | currentIndex | 101 | currentIndex = 0 // Index 0 is the beginning of the view | ||
102 | preferredHighlightBegin = visibleArea.yPosition | ||||
103 | preferredHighlightEnd = preferredHighlightBegin + currentItem.height | ||||
104 | highlightRangeMode = ListView.StrictlyEnforceRange | ||||
105 | | ||||
106 | highlightMoveDuration = 1 // This is not ideal: I would like to disable the highlight animation altogether | ||||
107 | | ||||
108 | // Get more messages | ||||
109 | model.sourceModel.requestMoreMessages() | ||||
110 | } | ||||
111 | } | ||||
64 | } | 112 | } | ||
65 | 113 | | |||
66 | footer: RowLayout { | 114 | footer: RowLayout { | ||
67 | enabled: page.device | 115 | enabled: page.device | ||
68 | TextField { | 116 | TextField { | ||
69 | id: message | 117 | id: message | ||
70 | Layout.fillWidth: true | 118 | Layout.fillWidth: true | ||
71 | placeholderText: i18n("Say hi...") | 119 | placeholderText: i18n("Say hi...") | ||
Show All 14 Lines |